Maison Problème commun Comment implémenter le contrôle de concurrence dans le langage Go

Comment implémenter le contrôle de concurrence dans le langage Go

Jun 08, 2023 pm 02:20 PM
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.

Comment implémenter le contrôle de concurrence dans le langage Go

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均已完成工作!
Copier après la connexion

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)}输出:
//监控中
//监控中
//监控中
//通知监控退出
//退出监控
Copier après la connexion

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退出
Copier après la connexion

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!

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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

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

Outils chauds

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)

Version Web Deepseek Entrée officielle Version Web Deepseek Entrée officielle Mar 12, 2025 pm 01:42 PM

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

Recherche approfondie Entrée du site officiel Deepseek Recherche approfondie Entrée du site officiel Deepseek Mar 12, 2025 pm 01:33 PM

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

Comment résoudre le problème des serveurs occupés pour Deepseek Comment résoudre le problème des serveurs occupés pour Deepseek Mar 12, 2025 pm 01:39 PM

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.