我最近开始学习Go语言,但是遇到了问题。我有一个简单的go例程,该例程可以将值返回或将值推入通道。我的主要fn代表一直在执行此例程,直到满足条件或数据用尽为止。这段代码似乎在“找到”频道上陷入僵局。我究竟做错了什么?
。
func workerRoutine(data Data, found chan bool, wg *sync.WaitGroup){ defer (*wg).Done() // data processing // return on false // multiple routines can set this at the same time found <-true } func main { // .... found:=make(chan bool) var wg sync.WaitGroup itemFound:=false Loop: for i:=0; i<limit; i++ { select { case <-found: itemFound = true break Loop default: if(some_check) { wg.Add(1) go workerRoutine(mdata,found,&wg) } } } wg.Wait() // use itemFound }
一种可能的解决方案是避免使用select语句,并为接收者(或发送者,或两者)使用单独的goroutine。例:
package main import "sync" func worker(res chan bool, wg *sync.WaitGroup) { res <- true wg.Done() } func receiver(res chan bool, wg *sync.WaitGroup) { for range res { } wg.Done() } func main() { var wg, wg2 sync.WaitGroup wg.Add(1) wg2.Add(10) found := make(chan bool) go receiver(found, &wg) for i := 0; i < 10; i++ { go worker(found, &wg2) } wg2.Wait() close(found) wg.Done() }