
本人是 golang 小白, 写一段代码, 通过go coroutine同时启动生产者和消费者,然后生产者没产生任何数据,消费者也没接收到任何数据,然后主线程就退出了
var waiter sync.WaitGroup func producer(data chan interface{}){ waiter.Add(1) defer func(){ waiter.Done() close(data) }() // start sending for i:=0 ; i > 100; i++{ data <- i } } func consumer(data chan interface{}){ waiter.Add(1) defer waiter.Done() end: for { select { case item, Ok:= <- data: if !Ok{ break end: }else { // do something } default: continue } } } func main(){ defer waiter.Wait() pipe := make(chan interface{}) go producer(pipe) go consumer(pipe) } 希望各位高手能指出我的错误
1 VicYu 2018-03-08 14:32:49 +08:00 主线程已经执行并结束,并不会等待各个 go 的执行完成的 |
2 SlipStupig OP @VicYu 我不是加了一个 WaitGroup,按道理说已经会堵塞啊 |
3 simple2025 2018-03-08 14:44:37 +08:00 大佬,又去学 golnag,NB |
4 gnenux 2018-03-08 14:46:41 +08:00 via iPhone for i:=0;i<100;i++ { data<- i } |
5 KIDJourney 2018-03-08 14:47:21 +08:00 @SlipStupig 你的主进程可能在 Add 前就结束了,你可以加个 sleep 试一下。 |
6 KIDJourney 2018-03-08 14:49:58 +08:00 @KIDJourney 忽略,看起来并不是这个原因。 |
7 picone 2018-03-08 14:52:42 +08:00 有没有考虑过一个问题,在 producer 和 consumer 执行之前,已经执行到 defer waiter.Wait(),那时候 waiter 还没有 Add 你可以把 WaitGroup.Add 放到 go routine 之前 |
8 VicYu 2018-03-08 14:59:15 +08:00 ```golang package main import ( "fmt" "sync" ) var wg sync.WaitGroup func test(i int) { fmt.Println(i) wg.Done() } func testAdd() { wg.Add(1) } func main() { defer wg.Wait() for i:= 0; i < 10; i++ { go testAdd() go test(i) } } ``` 你跑上面这个,多跑几次 |
9 SlipStupig OP |
10 SlipStupig OP @picone 确实是这样,go 的子线程是不堵塞的,然后 waitgroup 已经清空了不会再堵塞了 |
11 anthow 2018-03-08 17:23:02 +08:00 The main goroutine calls Add to set the number of goroutines to wait for. Then each of the goroutines runs and calls Done when finished. |
12 xwhxbg 2018-03-08 19:31:30 +08:00 看了下八成是 defer waiter 造成的吧,一般都是手动在最后调下 wg.Wait(),另外就是 select 如果 chan 还没数据会不断地执行 default 的语句,建议 consumer 加个 sleep 吧,进了 default 就 sleep 一下 |