gpt4 book ai didi

go - 所有goroutine都处于 sleep 状态-死锁(无限循环+选择)

转载 作者:数据小太阳 更新时间:2023-10-29 03:44:52 26 4
gpt4 key购买 nike

我有一个应用程序,每隔几秒钟就创建一个从api获取当前价格的例程。然后它将响应发送到监视例程以进行分析。如果监视器发现价格有明显变化,它会发送一个通知。
如果每次执行程序之间的延迟较大,则可以正常工作。如果它很小,它不会:“致命错误:所有goroutine都处于休眠-死锁状态!”被触发,程序崩溃。
我猜(?)死锁是由以下原因造成的:(1)监视器充斥着新的价格信息(并且未能及时分析这些信息);或(2)主功能被监视器的消息所淹没。
在主函数将新价格附加到一个切片上的同时,监视器正在遍历它,这一事实可能也有一些缺点。
如何解决这个问题?在阅读其他文章时,我认为“select”语句是一种神奇的治疗方法,但它似乎不是……

func main() {
ec := make(chan entry, 10)
mce := make (chan entry, 10)
mcn := make(chan string, 10)

go monitor(mce, mcn)

for {
go fetchData(ec)
select {
// get entries
case newEntry := <- ec:
log = append(log, newEntry)
mce <- newEntry
default:
{}
}

//check if any notifications received
select {
case newMsg := <- mcn:
fmt.Println(newMsg)
default:
{}
}

delay()
}
}

func monitor(mce <-chan entry, mcn chan<- string) {


for {
newEntry = <- mce

for _, item := range log {
// here - do some analysis comparing the newEntry against previous entries
// (essentially to see if notification should be triggered)
}

if should_send_notification {
mcn <- msg
}

}
}

func fetchData(ec chan<- entry) {

// here some code fetching newEntry from APIs

// send the newEntry back to the main function
ec <- newEntry

}

最佳答案

只需合并一个select并删除main函数的默认语句。删除默认语句不需要delay()函数,因为select case会阻塞并等待来自通道的某些消息:

func main() {
ec := make(chan entry, 10)
mce := make (chan entry, 10)
mcn := make(chan string, 10)

go monitor(mce, mcn)
go fetchData(ec)
for {
select {
// get entries
case newEntry := <- ec:
log = append(log, newEntry)
mce <- newEntry
//check if any notifications received
case newMsg := <- mcn:
fmt.Println(newMsg)
}
}
}

fetchdata(ec)便于实现类似的阻塞,并且不需要连续调用它:
func fetchData(ec chan<- entry) {

for {
// here some code fetching newEntry from APIs
// waiting data

// send the newEntry if I get data
ec <- newEntry
}

}

关于go - 所有goroutine都处于 sleep 状态-死锁(无限循环+选择),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53932184/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com