Maison développement back-end Golang La meilleure façon d'implémenter la programmation simultanée et asynchrone à l'aide du langage Go

La meilleure façon d'implémenter la programmation simultanée et asynchrone à l'aide du langage Go

Jun 04, 2023 am 09:31 AM
go语言 并发编程 异步编程

Avec l'amélioration des performances du matériel informatique, de plus en plus d'applications doivent gérer un grand nombre de tâches simultanées et asynchrones. Cela soulève la question : comment gérer ces tâches efficacement et garantir la qualité du code ? Le langage Go a la capacité inhérente de prendre en charge la programmation simultanée et asynchrone. Cet article présente la meilleure façon de mettre en œuvre la programmation simultanée et asynchrone à l'aide du langage Go.

1. Comprendre le modèle de programmation concurrente et asynchrone du langage Go

Le modèle de programmation concurrente et asynchrone du langage Go est implémenté sur la base de la goroutine et du canal. Goroutine est un thread léger qui peut exécuter plusieurs tâches simultanément dans un programme. Channel est un canal de communication entre goroutines, qui peut réaliser la transmission de données entre différentes goroutines.

Dans le langage Go, une nouvelle goroutine peut être démarrée en utilisant le mot-clé go. Comme indiqué ci-dessous :

go func() {
  // do something
}()
Copier après la connexion

Dans le code ci-dessus, func() représente le code de fonction à exécuter. Démarrer cette fonction avec le mot-clé go l'exécutera dans une nouvelle goroutine.

Dans le langage Go, le modèle CSP (Communicating Sequential Processes) est adopté, ce qui signifie que la concurrence et la collaboration s'effectuent via des canaux. Un canal a deux points de terminaison : l'envoi et la réception. La communication entre les goroutines peut être réalisée par des canaux d'envoi et de réception.

2. Comment créer et utiliser une chaîne

En langage Go, créez une chaîne via la fonction make. Ce qui suit consiste à créer un canal de type chaîne :

ch := make(chan string)
Copier après la connexion

Utilisez le symbole < pour envoyer des données au canal :

ch <- "Hello world"
Copier après la connexion

Utilisez le symbole < pour recevoir des données depuis le canal :

msg := <-ch
Copier après la connexion

Remarque : S'il n'y a aucune donnée à recevoir, le programme bloquera l'opération de réception. De même, si le canal est plein, l'opération d'envoi sera bloquée.

Il existe également un mot-clé select dans le langage Go qui peut être utilisé pour sélectionner l'exécution de goroutine. Select peut contenir plusieurs cas, chaque cas est une opération de réception ou d'envoi d'un canal. Lorsque select est exécuté, il sélectionnera au hasard un cas disponible pour l'exécution. Si aucun cas n'est disponible, il sera bloqué.

Voici un exemple :

ch1 := make(chan int)
ch2 := make(chan int)

go func() {
  for i := 0; i < 10; i++ {
    ch1 <- i
  }
}()

go func() {
  for i := 0; i < 10; i++ {
    ch2 <- i
  }
}()

for i := 0; i < 20; i++ {
  select {
  case v := <-ch1:
    fmt.Println("ch1:", v)
  case v := <-ch2:
    fmt.Println("ch2:", v)
  }
}
Copier après la connexion

Dans l'exemple ci-dessus, nous avons créé deux goroutines, une pour envoyer des données à ch1 et l'autre à ch2. Utilisez ensuite l'instruction select dans la goroutine principale pour surveiller les données de ch1 et ch2. Lorsque les données sont disponibles, l'instruction case correspondante est exécutée.

3. Utilisez WaitGroup pour contrôler l'exécution de goroutine

Normalement, nous devons attendre la fin de l'exécution de toutes les goroutines avant d'effectuer d'autres opérations. Vous pouvez utiliser WaitGroup dans le package de synchronisation pour répondre à cette exigence. WaitGroup peut être utilisé pour attendre la fin d'un groupe de goroutines.

Ce qui suit est un exemple :

var wg sync.WaitGroup

func main() {
  for i := 0; i < 10; i++ {
    wg.Add(1)
    go func() {
      defer wg.Done()
      // do something
    }()
  }

  wg.Wait()
  // All goroutines are done
}
Copier après la connexion

Dans l'exemple ci-dessus, nous avons créé 10 goroutines, et l'appel de la méthode Add dans WaitGroup indique que 10 goroutines seront exécutées. Utilisez ensuite defer stmt.Done() dans chaque goroutine pour indiquer à WaitGroup que la goroutine est terminée. Enfin, la méthode Wait est appelée dans la goroutine principale pour attendre que toutes les goroutines terminent leur exécution.

4. Utilisez sync.Mutex pour assurer la sécurité des données

En langage Go, si une variable sera accédée par plusieurs goroutines en même temps, alors vous devez utiliser un verrouiller pour assurer la sécurité des données. Les verrous peuvent être implémentés à l'aide de Mutex à partir du package de synchronisation.

Voici un exemple :

var mu sync.Mutex
var count int

func inc() {
  mu.Lock()
  defer mu.Unlock()
  count++
}

func main() {
  for i := 0; i < 10; i++ {
    go inc()
  }

  time.Sleep(time.Second)

  fmt.Println("count:", count)
}
Copier après la connexion

Dans l'exemple ci-dessus, nous avons créé un objet .Mutex pour garantir que l'accès à count est thread-safe. Dans la fonction inc, nous acquérons d'abord le verrou puis le libérons en différé. Dans la fonction principale, nous démarrons 10 goroutines inc pour accéder au nombre.

5. Utilisez le package contextuel pour gérer les délais d'attente et les annulations

En langage Go, nous pouvons utiliser le package contextuel pour gérer les délais d'attente et les annulations afin d'éviter les fuites goroutines et le gaspillage de ressources . Le contexte peut définir des délais et annuler les signaux. Toutes les goroutines seront annulées lorsque le signal est déclenché.

Ce qui suit est un exemple :

ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()

ch := make(chan int)

go func() {
  time.Sleep(time.Second * 5)
  ch <- 1
}()

select {
case <-ch:
  fmt.Println("received")
case <-ctx.Done():
  fmt.Println("timeout or cancelled")
}
Copier après la connexion

Dans l'exemple ci-dessus, nous utilisons la fonction context.WithTimeout pour créer un objet Context avec un délai d'attente de 3 secondes et démarrer un goroutine pour attendre 5 secondes. Dans l'instruction select, si la goroutine se termine dans les 3 secondes, imprimez « reçu », sinon imprimez « timeout ou annulé ».

6. Résumé

La programmation simultanée et asynchrone peut être facilement implémentée à l'aide du langage Go. En utilisant des goroutines et des canaux, nous pouvons créer des modèles de concurrence efficaces. Dans le même temps, l'utilisation de WaitGroup, Mutex et Context peut rendre notre programme plus sûr et plus robuste.

Bien sûr, si elles sont utilisées de manière inappropriée, une concurrence élevée et une programmation asynchrone peuvent également causer certains problèmes, tels que des conditions de concurrence, des blocages, la famine et d'autres problèmes. Par conséquent, lorsque vous utilisez une programmation concurrente et asynchrone, veillez à faire attention à la qualité et à l'exactitude du code.

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

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

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)

Quelles bibliothèques sont utilisées pour les opérations du numéro de point flottantes en Go? Quelles bibliothèques sont utilisées pour les opérations du numéro de point flottantes en Go? Apr 02, 2025 pm 02:06 PM

La bibliothèque utilisée pour le fonctionnement du numéro de point flottante dans le langage go présente comment s'assurer que la précision est ...

Quel est le problème avec le fil de file d'attente dans GO's Crawler Colly? Quel est le problème avec le fil de file d'attente dans GO's Crawler Colly? Apr 02, 2025 pm 02:09 PM

Problème de threading de file d'attente dans Go Crawler Colly explore le problème de l'utilisation de la bibliothèque Crawler Crawler dans le langage Go, les développeurs rencontrent souvent des problèmes avec les threads et les files d'attente de demande. � ...

Dans Go, pourquoi les chaînes d'impression avec println et string () ont-elles des effets différents? Dans Go, pourquoi les chaînes d'impression avec println et string () ont-elles des effets différents? Apr 02, 2025 pm 02:03 PM

La différence entre l'impression de chaîne dans le langage go: la différence dans l'effet de l'utilisation de fonctions println et string () est en Go ...

Comment résoudre le problème de conversion de type user_id lors de l'utilisation du flux redis pour implémenter les files d'attente de messages dans le langage Go? Comment résoudre le problème de conversion de type user_id lors de l'utilisation du flux redis pour implémenter les files d'attente de messages dans le langage Go? Apr 02, 2025 pm 04:54 PM

Le problème de l'utilisation de Redessstream pour implémenter les files d'attente de messages dans le langage GO consiste à utiliser le langage GO et redis ...

Quelle est la différence entre la structure de définition des mots clés `var` et« type »dans le langage Go? Quelle est la différence entre la structure de définition des mots clés `var` et« type »dans le langage Go? Apr 02, 2025 pm 12:57 PM

Deux façons de définir les structures dans le langage GO: la différence entre les mots clés VAR et le type. Lorsque vous définissez des structures, GO Language voit souvent deux façons d'écrire différentes: d'abord ...

Quelles bibliothèques de GO sont développées par de grandes entreprises ou fournies par des projets open source bien connus? Quelles bibliothèques de GO sont développées par de grandes entreprises ou fournies par des projets open source bien connus? Apr 02, 2025 pm 04:12 PM

Quelles bibliothèques de GO sont développées par de grandes entreprises ou des projets open source bien connus? Lors de la programmation en Go, les développeurs rencontrent souvent des besoins communs, ...

Que dois-je faire si les étiquettes de structure personnalisées à Goland ne sont pas affichées? Que dois-je faire si les étiquettes de structure personnalisées à Goland ne sont pas affichées? Apr 02, 2025 pm 05:09 PM

Que dois-je faire si les étiquettes de structure personnalisées à Goland ne sont pas affichées? Lorsque vous utilisez Goland pour le développement du langage GO, de nombreux développeurs rencontreront des balises de structure personnalisées ...

Lorsque vous utilisez SQL.Open, pourquoi ne signale pas une erreur lorsque DSN passe vide? Lorsque vous utilisez SQL.Open, pourquoi ne signale pas une erreur lorsque DSN passe vide? Apr 02, 2025 pm 12:54 PM

Lorsque vous utilisez SQL.Open, pourquoi le DSN ne signale-t-il pas une erreur? En langue go, sql.open ...

See all articles