次のコードは、リンク リスト内の要素を交互に出力する 2 つのゴルーチンの使用を実装しています。ただし、最終時刻が表示されないと印刷結果が表示されないという、かなり奇妙な問題に悩まされています。寝る。理論的には、標準出力にはバッファがありません。誰かがガイダンスを提供できますか?
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) }
2つのGoroutineが開始される前にwaitgroupカウンターがインクリメントされるため、メインGoroutineでwg.Add(1)
を呼び出す必要があります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 中国語 Web サイトの他の関連記事を参照してください。