Maison  >  Article  >  développement back-end  >  Pourquoi ne puis-je pas voir le résultat si je ne dors pas à la fin ?

Pourquoi ne puis-je pas voir le résultat si je ne dors pas à la fin ?

WBOY
WBOYavant
2024-02-06 11:21:03714parcourir

Pourquoi ne puis-je pas voir le résultat si je ne dors pas à la fin ?

Contenu de la question

Le code suivant implémente l'utilisation de deux goroutines pour imprimer alternativement des éléments dans la liste chaînée. Cependant, il souffre d'un problème assez étrange où le résultat imprimé n'est pas visible sans l'heure finale. dormir. Théoriquement, stdout n'a pas de tampon. Quelqu'un peut-il fournir des conseils ?

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

Bonne réponse

Vous devez appeler wg.Add(1) sur la Goroutine principale car le compteur des groupes d'attente est incrémenté avant que les 2 Goroutines démarrées n'arrivent avant main() wg.Wait() est un scénario valide. Si son compteur est à 0, wg.Wait() ne bloque pas, main() renvoie, et donc toute l'application se termine : 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)rrreee

(du travailleur, de course Supprimez wg.Add(1) dans

Voir : Où placer wg.Add()

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer