首頁  >  文章  >  後端開發  >  為什麼我最後不睡覺就看不到輸出

為什麼我最後不睡覺就看不到輸出

WBOY
WBOY轉載
2024-02-06 11:21:03714瀏覽

為什麼我最後不睡覺就看不到輸出

問題內容

下面的程式碼實作了使用兩個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中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除