下面的程式碼實作了使用兩個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) }
您必須在主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() 的位置
以上是為什麼我最後不睡覺就看不到輸出的詳細內容。更多資訊請關注PHP中文網其他相關文章!