问题内容
下面的代码实现了使用两个goroutine来交替打印链表中的元素。然而,它遇到了一个相当奇怪的问题,即在没有最终时间的情况下打印结果不可见。睡眠。理论上,stdout 没有缓冲区。有人可以提供一些指导吗?
import ( "context" "fmt" "sync" ) type ListNode struct { val int next *ListNode } func NewLinkedList() (head *ListNode) { var cur *ListNode for i := 0; i < 100; i++ { if cur == nil { cur = &ListNode{val: i} head = cur } else { cur.next = &ListNode{val: i} cur = cur.next } } return } func main() { ll := NewLinkedList() wg := sync.WaitGroup{} var a = make(chan *ListNode, 1) var b = make(chan *ListNode, 1) ctx, cancel := context.WithCancel(context.Background()) worker := func(name string, input, output chan *ListNode) { wg.Add(1) defer wg.Done() for { select { case n := <-input: if n == nil { break } fmt.Printf("%s: %dn", name, n.val) if n.next != nil { output <- n.next } else { cancel() break } case <-ctx.Done(): break } } } go worker("a", a, b) go worker("b", b, a) a <- ll wg.Wait() //time.Sleep(time.Millisecond) }
正确答案
您必须在主 Goroutine 上调用 wg.Add(1)
,因为在 2 个启动的 Goroutine 增加 waitgroup 计数器之前 main()
到达 wg.Wait()
是一个有效的场景。如果其计数器为 0,则 wg.Wait()
不会阻塞,main()
返回,因此整个应用程序终止:
wg.Add(1) go worker("a", a, b) wg.Add(1) go worker("a", a, b)
(当然,从工作人员中删除 wg.Add(1)
。)
请参阅:放置 wg.Add() 的位置
想要了解更多内容,请持续关注码农资源网,一起探索发现编程世界的无限可能!
本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
如有侵权请发送邮件至1943759704@qq.com删除
码农资源网 » 为什么我最后不睡觉就看不到输出
本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
如有侵权请发送邮件至1943759704@qq.com删除
码农资源网 » 为什么我最后不睡觉就看不到输出