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