Table des matières
Contenu de la question
Solution de contournement
Maison développement back-end Golang Demandez à Go d'exécuter toutes les goroutines avant de continuer

Demandez à Go d'exécuter toutes les goroutines avant de continuer

Feb 11, 2024 pm 05:20 PM
go语言

在继续之前要求 Go 运行所有 goroutine

Lors de la programmation simultanée, nous rencontrons souvent des situations où nous devons attendre que toutes les goroutines soient terminées avant de poursuivre l'exécution. En langage Go, nous pouvons atteindre cet objectif en utilisant WaitGroup. WaitGroup est un sémaphore de comptage qui peut être utilisé pour attendre la fin d'un groupe de goroutines. Avant de continuer, nous devons appeler la méthode Wait de WaitGroup pour nous assurer que toutes les goroutines ont terminé leurs tâches. Dans cet article, nous présenterons comment utiliser correctement WaitGroup pour gérer l'ordre d'exécution des goroutines.

Contenu de la question

J'ai besoin du planificateur Golang pour exécuter toutes les goroutines avant de continuer, runtime.gosched() ne peut pas le résoudre.

Le problème est que la routine go s'exécute si vite que le "select" dans start() s'exécute après le "select" dans stopstream() puis "case <-chanstopstream:" le destinataire n'est pas prêt pour l'expéditeur "case retchan <-true :". Il s'avère que lorsque cela se produit, le résultat est le même comportement que lorsque stopstream() se bloque

Exécutez ce code https://go.dev/play/p/dq85xqju2q_z Plusieurs fois, vous verrez ces deux réponses Réponse attendue lorsqu'il n'est pas suspendu :

2009/11/10 23:00:00 start
2009/11/10 23:00:00 receive chan
2009/11/10 23:00:03 end
Copier après la connexion

Réponse attendue en cas de suspension, mais pas si rapide en cas de suspension :

2009/11/10 23:00:00 start
2009/11/10 23:00:00 default
2009/11/10 23:00:01 timer
2009/11/10 23:00:04 end
Copier après la connexion

Code

package main

import (
    &quot;log&quot;
    &quot;runtime&quot;
    &quot;sync&quot;
    &quot;time&quot;
)

var wg sync.WaitGroup

func main() {
    wg.Add(1)
    //run multiples routines on a huge system
    go start()
    wg.Wait()
}
func start() {
    log.Println(&quot;Start&quot;)
    chanStopStream := make(chan bool)
    go stopStream(chanStopStream)
    select {
    case &lt;-chanStopStream:
        log.Println(&quot;receive chan&quot;)
    case &lt;-time.After(time.Second): //if stopStream hangs do not wait more than 1 second
        log.Println(&quot;TIMER&quot;)
        //call some crash alert
    }
    time.Sleep(3 * time.Second)
    log.Println(&quot;end&quot;)
    wg.Done()
}

func stopStream(retChan chan bool) {
    //do some work that can be faster then caller or not
    runtime.Gosched()
    //time.Sleep(time.Microsecond) //better solution then runtime.Gosched()
    //time.Sleep(2 * time.Second) //simulate when this routine hangs more than 1 second
    select {
    case retChan &lt;- true:
    default: //select/default is used because if the caller times out this routine will hangs forever
        log.Println(&quot;default&quot;)
    }
}
Copier après la connexion

Solution de contournement

Il n'y a aucun moyen d'exécuter toutes les autres goroutines avant de continuer l'exécution de la goroutine actuelle.

Correction du problème en s'assurant que la goroutine ne se bloque pas stopstream :

Option 1 : Remplacez chanstopstream par canal tamponné chanstopstream 更改为缓冲通道。这确保了 stopstream. Cela garantit que

peut envoyer des valeurs sans blocage.

func start() {
    log.println(&quot;start&quot;)
    chanstopstream := make(chan bool, 1) // &lt;--- buffered channel
    go stopstream(chanstopstream)
    ...
}

func stopstream(retchan chan bool) {
    ...
    // always send. no select/default needed.
    retchan &lt;- true
}
Copier après la connexion
https://www.php.cn/link/56e48d306028f2a6c2ebf677f7e8f800

Option 2

 : Fermez le canal au lieu d'envoyer la valeur. Les chaînes peuvent toujours être fermées par l'expéditeur. Reçoit une valeur zéro sur un canal fermé qui renvoie le type de valeur du canal.

func start() {
    log.Println(&quot;Start&quot;)
    chanStopStream := make(chan bool) // buffered channel not required
    go stopStream(chanStopStream)
    ...

func stopStream(retChan chan bool) {
    ...
    close(retChan)
}
Copier après la connexion
https://www.php.cn/link/a1aa0c486fb1a7ddd47003884e1fc67f🎜

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 de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Tags d'article chaud

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment utiliser la réflexion pour accéder aux champs et méthodes privés dans Golang Comment utiliser la réflexion pour accéder aux champs et méthodes privés dans Golang May 03, 2024 pm 12:15 PM

Comment utiliser la réflexion pour accéder aux champs et méthodes privés dans Golang

Conseils pour créer dynamiquement de nouvelles fonctions dans les fonctions Golang Conseils pour créer dynamiquement de nouvelles fonctions dans les fonctions Golang Apr 25, 2024 pm 02:39 PM

Conseils pour créer dynamiquement de nouvelles fonctions dans les fonctions Golang

La différence entre les tests de performances et les tests unitaires en langage Go La différence entre les tests de performances et les tests unitaires en langage Go May 08, 2024 pm 03:09 PM

La différence entre les tests de performances et les tests unitaires en langage Go

À quels pièges devons-nous prêter attention lors de la conception de systèmes distribués avec la technologie Golang ? À quels pièges devons-nous prêter attention lors de la conception de systèmes distribués avec la technologie Golang ? May 07, 2024 pm 12:39 PM

À quels pièges devons-nous prêter attention lors de la conception de systèmes distribués avec la technologie Golang ?

Bibliothèques technologiques Golang et outils utilisés dans l'apprentissage automatique Bibliothèques technologiques Golang et outils utilisés dans l'apprentissage automatique May 08, 2024 pm 09:42 PM

Bibliothèques technologiques Golang et outils utilisés dans l'apprentissage automatique

L'évolution de la convention de dénomination des fonctions Golang L'évolution de la convention de dénomination des fonctions Golang May 01, 2024 pm 03:24 PM

L'évolution de la convention de dénomination des fonctions Golang

Le rôle de la technologie Golang dans le développement de l'IoT mobile Le rôle de la technologie Golang dans le développement de l'IoT mobile May 09, 2024 pm 03:51 PM

Le rôle de la technologie Golang dans le développement de l'IoT mobile

Les paramètres de variables Golang peuvent-ils être utilisés pour les valeurs de retour de fonction ? Les paramètres de variables Golang peuvent-ils être utilisés pour les valeurs de retour de fonction ? Apr 29, 2024 am 11:33 AM

Les paramètres de variables Golang peuvent-ils être utilisés pour les valeurs de retour de fonction ?

See all articles