求助! golang chan 同步小白问题

2018-03-08 14:28:53 +08:00
 SlipStupig

本人是 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)

}

希望各位高手能指出我的错误 😱

2431 次点击
所在节点    程序员
12 条回复
VicYu
2018-03-08 14:32:49 +08:00
主线程已经执行并结束,并不会等待各个 go 的执行完成的
SlipStupig
2018-03-08 14:39:08 +08:00
@VicYu 我不是加了一个 WaitGroup,按道理说已经会堵塞啊
chenqh
2018-03-08 14:44:37 +08:00
大佬,又去学 golnag,NB
gnenux
2018-03-08 14:46:41 +08:00
for i:=0;i<100;i++ {
data<- i
}
KIDJourney
2018-03-08 14:47:21 +08:00
@SlipStupig 你的主进程可能在 Add 前就结束了,你可以加个 sleep 试一下。
KIDJourney
2018-03-08 14:49:58 +08:00
@KIDJourney 忽略,看起来并不是这个原因。
picone
2018-03-08 14:52:42 +08:00
有没有考虑过一个问题,在 producer 和 consumer 执行之前,已经执行到 defer waiter.Wait(),那时候 waiter 还没有 Add
你可以把 WaitGroup.Add 放到 go routine 之前
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)
}
}
```

你跑上面这个,多跑几次
SlipStupig
2018-03-08 15:00:46 +08:00
@chenqh 不努力就被淘汰了啊

@KIDJourney 确实是这样,我现在改成在执行线程之前先 add(2),就可以了
SlipStupig
2018-03-08 15:10:07 +08:00
@picone 确实是这样,go 的子线程是不堵塞的,然后 waitgroup 已经清空了不会再堵塞了
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.
xwhxbg
2018-03-08 19:31:30 +08:00
看了下八成是 defer waiter 造成的吧,一般都是手动在最后调下 wg.Wait(),另外就是 select 如果 chan 还没数据会不断地执行 default 的语句,建议 consumer 加个 sleep 吧,进了 default 就 sleep 一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/436147

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX