本人是 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
chenqh 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 1
@SlipStupig 你的主进程可能在 Add 前就结束了,你可以加个 sleep 试一下。
|
6
KIDJourney 2018-03-08 14:49:58 +08:00
@KIDJourney 忽略,看起来并不是这个原因。
|
7
picone 2018-03-08 14:52:42 +08:00 1
有没有考虑过一个问题,在 producer 和 consumer 执行之前,已经执行到 defer waiter.Wait(),那时候 waiter 还没有 Add
你可以把 WaitGroup.Add 放到 go routine 之前 |
8
VicYu 2018-03-08 14:59:15 +08:00 1
```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 一下
|