Comment implémenter le contrôle de concurrence dans le langage Go
Méthodes d'implémentation du contrôle de concurrence dans le langage go : 1. WaitGroup, le traitement des tâches de plusieurs goroutines a une relation de dépendance ou d'épissage ; 2. Channel, vous pouvez activement annuler le transfert de données dans plusieurs groutines ; remplacer WaitGroup Work pour répondre aux fonctions de Context ; 3. Contexte, propagation du signal entre les groutines multi-niveaux, y compris la propagation des métadonnées, l'annulation de la propagation du signal, le contrôle du délai d'attente, etc.
L'environnement d'exploitation de cet article : système Windows 10, version go1.20, ordinateur Dell g3.
Dans Golang, vous pouvez ouvrir une goroutine via le mot-clé go, afin de pouvoir facilement écrire du code simultané dans Go. Mais comment contrôler efficacement ces groutines qui s'exécutent simultanément ?
Quand il s'agit de contrôle de concurrence, la première chose à laquelle beaucoup de gens pensent, ce sont les verrous. Golang fournit également des mécanismes liés au verrouillage, notamment le verrouillage mutex sync.Mutex et le verrouillage en lecture-écriture sync.RWMutex. En plus des verrous, il existe également des opérations atomiques sync/atomic, etc. Cependant, ces mécanismes se concentrent sur la sécurité simultanée des données des goroutines. Ce que cet article veut discuter, c'est du contrôle du comportement de concurrence de goroutine.
Dans le contrôle des comportements simultanés des goroutines, il existe trois méthodes courantes, à savoir WaitGroup, Channel et Context.
WaitGroup
WaitGroup se trouve sous le package de synchronisation. Son utilisation est la suivante.
func main() { var wg sync.WaitGroup wg.Add(2) //添加需要完成的工作量2 go func() { wg.Done() //完成工作量1 fmt.Println("goroutine 1 完成工作!") }() go func() { wg.Done() //完成工作量1 fmt.Println("goroutine 2 完成工作!") }() wg.Wait() //等待工作量2均完成 fmt.Println("所有的goroutine均已完成工作!")}输出: //goroutine 2 完成工作! //goroutine 1 完成工作! //所有的goroutine均已完成工作!
WaitGroup Cette méthode de contrôle de concurrence est particulièrement adaptée aux situations où une certaine tâche nécessite que plusieurs goroutines travaillent ensemble. Chaque goroutine ne peut effectuer qu'une partie de la tâche. La tâche n'est terminée que lorsque toutes les goroutines le sont. complété. WaitGroup a donc la même signification que son nom, qui est une façon d'attendre.
Cependant, dans les affaires réelles, il existe un scénario : lorsqu'une certaine exigence est remplie, une certaine goroutine doit être activement notifiée pour mettre fin. Par exemple, si nous démarrons une goroutine de surveillance en arrière-plan, lorsque la surveillance n'est plus nécessaire, nous devons notifier la goroutine de surveillance de la fin, sinon elle continuera à tourner au ralenti et provoquera des fuites.
Channel
Pour le scénario ci-dessus, WaitGroup ne peut rien faire. La méthode la plus simple que l'on puisse imaginer est de définir une variable globale et de la notifier en modifiant cette variable ailleurs. La goroutine d'arrière-plan vérifiera constamment cette variable si elle constate que la variable a changé, elle se fermera cependant. est quelque peu encombrant. Dans ce cas, canal+sélection peut s'avérer utile.
func main() { exit := make(chan bool) go func() { for { select { case <-exit: fmt.Println("退出监控") return default: fmt.Println("监控中") time.Sleep(2 * time.Second) } } }() time.Sleep(5 * time.Second) fmt.Println("通知监控退出") exit <- true //防止main goroutine过早退出 time.Sleep(5 * time.Second)}输出: //监控中 //监控中 //监控中 //通知监控退出 //退出监控
Cette combinaison canal+sélection est une manière plus élégante de notifier la goroutine de la fin.
Cependant, cette solution présente également des limites. Imaginez, et s'il y avait plusieurs goroutines qui devaient toutes être contrôlées pour se terminer ? Et si ces goroutines engendraient d’autres goroutines ? Bien sûr, nous pouvons définir de nombreux canaux pour résoudre ce problème, mais la chaîne relationnelle de goroutine conduit à la complexité de ce scénario.
Context
Les scénarios ci-dessus sont courants sous le modèle d'architecture CS. Dans Go, une goroutine distincte (A) est souvent ouverte pour chaque client afin de gérer sa série de requêtes, et souvent un seul A demandera également d'autres services (démarre une autre goroutine B), et B peut également demander une autre goroutine C, C. envoie ensuite la requête au serveur de Databse, par exemple. Imaginez que lorsque le client se déconnecte, A, B et C qui lui sont associés doivent se fermer immédiatement avant que le système puisse récupérer les ressources occupées par A, B et C. Quitter A est simple, mais comment avertir B et C de quitter également ?
À ce moment, le Contexte apparaît.
func A(ctx context.Context, name string) { go B(ctx ,name) //A调用了B for { select { case <-ctx.Done(): fmt.Println(name, "A退出") return default: fmt.Println(name, "A do something") time.Sleep(2 * time.Second) } }}func B(ctx context.Context, name string) { for { select { case <-ctx.Done(): fmt.Println(name, "B退出") return default: fmt.Println(name, "B do something") time.Sleep(2 * time.Second) } }}func main() { ctx, cancel := context.WithCancel(context.Background()) go A(ctx, "【请求1】") //模拟client来了1个连接请求 time.Sleep(3 * time.Second) fmt.Println("client断开连接,通知对应处理client请求的A,B退出") cancel() //假设满足某条件client断开了连接,那么就传播取消信号,ctx.Done()中得到取消信号 time.Sleep(3 * time.Second)}输出: //【请求1】 A do something //【请求1】 B do something //【请求1】 A do something //【请求1】 B do something //client断开连接,通知对应处理client请求的A,B退出 //【请求1】 B退出 //【请求1】 A退出
Dans l'exemple, une demande de connexion est simulée par le client et Goroutine A est ouverte en conséquence pour le traitement A et B utilisent le contexte pour le suivi. Annuler la notification de la fonction Une fois annulées, les deux goroutines seront terminées.
C'est la capacité de contrôle de Context. C'est comme un contrôleur. Après avoir appuyé sur le commutateur, tous les sous-contextes basés sur ce contexte ou dérivés de celui-ci recevront des notifications, puis des opérations de nettoyage pourront être effectuées. , et publie enfin le goroutine, qui résout avec élégance le problème du goroutine incontrôlable après le démarrage.
L'utilisation détaillée de Context dépasse la portée de cet article. Il y aura un article de suivi expliquant spécifiquement le package Context, alors restez à l’écoute.
Summary
Cet article répertorie trois modes de contrôle du comportement de concurrence dans Golang. Il n’y a pas de bonne ou de mauvaise distinction entre les modes, cela dépend simplement de l’utilisation de solutions appropriées aux différents scénarios. Dans les projets réels, plusieurs méthodes sont souvent utilisées en combinaison.
- WaitGroup : Le traitement des tâches de plusieurs goroutines a des dépendances ou des relations d'épissage.
- channel+select : Vous pouvez annuler activement la goroutine ; le transfert de données dans plusieurs groutines ; le canal peut remplacer le travail de WaitGroup, mais cela augmentera la complexité de la logique du code ; plusieurs canaux peuvent répondre aux fonctions de Context ; , et de même, cela rendra la logique du code complexe.
- Contexte : Propagation du signal entre groutines multi-niveaux (y compris propagation des métadonnées, annulation de la propagation du signal, contrôle du délai d'attente, etc.).
Dans Golang, vous pouvez ouvrir une goroutine via le mot-clé go, afin de pouvoir facilement écrire du code simultané dans Go. Mais comment contrôler efficacement ces groutines qui s'exécutent simultanément ?
Quand il s'agit de contrôle de concurrence, la première chose à laquelle beaucoup de gens pensent, ce sont les verrous. Golang fournit également des mécanismes liés au verrouillage, notamment le verrouillage mutex sync.Mutex et le verrouillage en lecture-écriture sync.RWMutex. En plus des verrous, il existe également des opérations atomiques sync/atomic, etc. Cependant, ces mécanismes se concentrent sur la sécurité simultanée des données des goroutines. Ce que cet article veut discuter, c'est du contrôle du comportement de concurrence de goroutine.
Dans le contrôle du comportement simultané des goroutines, il existe trois méthodes courantes, à savoir WaitGroup, Channel et Context.
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

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

Sujets chauds

La profondeur domestique de l'IA Dark Horse a fortement augmenté, choquant l'industrie mondiale de l'IA! Cette société chinoise de renseignement artificiel, qui n'a été créée que depuis un an et demi, a gagné des éloges des utilisateurs mondiaux pour ses maquettes gratuites et open source, Deepseek-V3 et Deepseek-R1. Deepseek-R1 est désormais entièrement lancé, avec des performances comparables à la version officielle d'Openaio1! Vous pouvez vivre ses fonctions puissantes sur la page Web, l'application et l'interface API. Méthode de téléchargement: prend en charge les systèmes iOS et Android, les utilisateurs peuvent le télécharger via l'App Store; Version Web Deepseek Entrée officielle: HT

Au début de 2025, l'IA domestique "Deepseek" a fait un début magnifique! Ce modèle d'IA gratuit et open source a une performance comparable à la version officielle d'OpenAI d'Openai, et a été entièrement lancé sur le côté Web, l'application et l'API, prenant en charge l'utilisation multi-terminale des versions iOS, Android et Web. Recherche approfondie du site officiel de Deepseek et du guide d'utilisation: Adresse officielle du site Web: https://www.deepseek.com/using étapes pour la version Web: cliquez sur le lien ci-dessus pour entrer le site officiel Deepseek. Cliquez sur le bouton "Démarrer la conversation" sur la page d'accueil. Pour la première utilisation, vous devez vous connecter avec votre code de vérification de téléphone mobile. Après vous être connecté, vous pouvez entrer dans l'interface de dialogue. Deepseek est puissant, peut écrire du code, lire des fichiers et créer du code

Deepseek: Comment gérer l'IA populaire qui est encombré de serveurs? En tant qu'IA chaude en 2025, Deepseek est gratuit et open source et a une performance comparable à la version officielle d'Openaio1, qui montre sa popularité. Cependant, une concurrence élevée apporte également le problème de l'agitation du serveur. Cet article analysera les raisons et fournira des stratégies d'adaptation. Entrée de la version Web Deepseek: https://www.deepseek.com/deepseek serveur Raison: Accès simultané: des fonctionnalités gratuites et puissantes de Deepseek attirent un grand nombre d'utilisateurs à utiliser en même temps, ce qui entraîne une charge de serveur excessive. Cyber Attack: Il est rapporté que Deepseek a un impact sur l'industrie financière américaine.