Go语言 为什么我最后不睡觉就看不到输出

ufj5ltwl  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(92)

下面的代码实现了使用两个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: %d\n", 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)
}
2izufjch

2izufjch1#

你必须在主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)

(And当然从worker中删除wg.Add(1)
请参阅:在何处放置wg.Add()

相关问题