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

WBOY
Release: 2024-02-06 11:22:09
forward
717 people have browsed it

Why cant I see the output if I dont 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)
}
Copy after login

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)
Copy after login

(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!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template