Home  >  Article  >  Backend Development  >  Why can’t I see the output if I don’t sleep at the end?

Why can’t I see the output if I don’t sleep at the end?

WBOY
WBOYforward
2024-02-06 11:21:03685browse

Why can’t I see the output if I don’t sleep at the end?

Question content

The following code implements the use of two goroutines to alternately print elements in the linked list. However, it suffers from a rather strange problem where the printed result is not visible without the final time. sleep. Theoretically, stdout has no buffer. Can anyone provide some guidance?

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)
}

Correct answer

You must call wg.Add(1) on the main Goroutine because the waitgroup counter is incremented before the 2 started Goroutinesmain () Reaching wg.Wait() is a valid scenario. If its counter is 0, wg.Wait() does not block, main() returns, and therefore the entire application terminates:

wg.Add(1)
go worker("a", a, b)
wg.Add(1)
go worker("a", a, b)

(of course, starting from Remove wg.Add(1) from staff.)

See: Where to place wg.Add()

The above is the detailed content of Why can’t I see the output if I don’t sleep at the end?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete