Maison > développement back-end > Golang > le corps du texte

Comment utiliser Goroutines pour le traitement simultané dans Go

Linda Hamilton
Libérer: 2024-10-12 06:31:02
original
565 Les gens l'ont consulté

How to Use Goroutines for Concurrent Processing in Go

La concurrence est l'une des fonctionnalités déterminantes de Go, ce qui en fait un langage fantastique pour créer des applications évolutives et hautes performances. Dans cet article, nous explorerons les Goroutines, qui vous permettent d'exécuter des fonctions simultanément dans Go, donnant ainsi à vos applications un sérieux gain d'efficacité. Que vous travailliez sur un serveur Web, un processeur de données ou tout autre type d'application, Goroutines peut vous aider à faire plus avec moins.

Voici ce que nous allons aborder :

  • Qu'est-ce que les Goroutines et comment elles fonctionnent.
  • Comment créer et utiliser des Goroutines.
  • Synchronisation des Goroutines avec les WaitGroups et les canaux.
  • Pièges courants et meilleures pratiques pour travailler avec Goroutines.

Commençons ! ?


Que sont les Goroutines ? ?

Les Goroutines sont des threads légers gérés par le runtime Go, vous permettant d'exécuter des fonctions simultanément. Contrairement aux threads au niveau du système d’exploitation, les Goroutines sont beaucoup moins chères et plus efficaces. Vous pouvez générer des milliers de Goroutines sans surcharger votre système, ce qui les rend idéales pour les tâches simultanées.

Principales caractéristiques :

  • Efficace : les Goroutines utilisent un minimum de mémoire et démarrent rapidement.
  • Exécution simultanée : ils peuvent exécuter plusieurs fonctions en même temps, vous aidant ainsi à gérer des tâches en parallèle.
  • Facile à utiliser : vous n'avez pas besoin de gérer une logique de thread complexe.

Créer et utiliser des Goroutines

Créer une Goroutine est incroyablement simple : il suffit d'utiliser le mot-clé go avant un appel de fonction. Regardons un exemple rapide.

Exemple de base :

package main

import (
    "fmt"
    "time"
)

func printMessage(message string) {
    for i := 0; i < 5; i++ {
        fmt.Println(message)
        time.Sleep(500 * time.Millisecond)
    }
}

func main() {
    go printMessage("Hello from Goroutine!")  // This runs concurrently
    printMessage("Hello from main!")
}
Copier après la connexion

Dans cet exemple, printMessage est appelé comme Goroutine avec go printMessage("Hello from Goroutine!"), ce qui signifie qu'il s'exécutera en même temps que la fonction principale.


Synchronisation des Goroutines avec les WaitGroups

Étant donné que les Goroutines s'exécutent simultanément, elles peuvent terminer dans n'importe quel ordre. Pour vous assurer que toutes les Goroutines sont terminées avant de continuer, vous pouvez utiliser un WaitGroup du package de synchronisation de Go.

Exemple avec WaitGroup :

package main

import (
    "fmt"
    "sync"
    "time"
)

func printMessage(message string, wg *sync.WaitGroup) {
    defer wg.Done() // Notify WaitGroup that the Goroutine is done
    for i := 0; i < 5; i++ {
        fmt.Println(message)
        time.Sleep(500 * time.Millisecond)
    }
}

func main() {
    var wg sync.WaitGroup

    wg.Add(1)
    go printMessage("Hello from Goroutine!", &wg)

    wg.Add(1)
    go printMessage("Hello again!", &wg)

    wg.Wait()  // Wait for all Goroutines to finish
    fmt.Println("All Goroutines are done!")
}
Copier après la connexion

Ici, nous ajoutons wg.Add(1) pour chaque Goroutine et appelons wg.Done() lorsque la Goroutine est terminée. Enfin, wg.Wait() met la fonction principale en pause jusqu'à ce que toutes les Goroutines soient terminées.


Communiquer entre Goroutines avec des canaux

Les

Canaux sont le moyen intégré de Go permettant aux Goroutines de communiquer. Ils vous permettent de transmettre des données en toute sécurité entre Goroutines, garantissant ainsi qu'aucune course aux données ne se produise.

Exemple de canal de base :

package main

import (
    "fmt"
)

func sendData(channel chan string) {
    channel <- "Hello from the channel!"
}

func main() {
    messageChannel := make(chan string)

    go sendData(messageChannel)

    message := <-messageChannel  // Receive data from the channel
    fmt.Println(message)
}
Copier après la connexion

Dans cet exemple, sendData envoie un message à messageChannel et la fonction principale le reçoit. Les canaux aident à synchroniser les Goroutines en bloquant jusqu'à ce que l'expéditeur et le destinataire soient prêts.

Utilisation de canaux tamponnés

Vous pouvez également créer des canaux tamponnés qui permettent de stocker un nombre défini de valeurs dans le canal avant qu'il ne se bloque. Ceci est utile lorsque l'on souhaite gérer les flux de données sans nécessairement synchroniser chaque Goroutine.

func main() {
    messageChannel := make(chan string, 2)  // Buffered channel with capacity of 2

    messageChannel <- "Message 1"
    messageChannel <- "Message 2"
    // messageChannel <- "Message 3" // This would block as the buffer is full

    fmt.Println(<-messageChannel)
    fmt.Println(<-messageChannel)
}
Copier après la connexion

Les canaux tamponnés ajoutent un peu plus de flexibilité, mais il est important de gérer soigneusement la taille des tampons pour éviter les blocages.


Pièges courants et meilleures pratiques

  1. Éviter de bloquer les Goroutines : Si une Goroutine se bloque et qu'il n'y a aucun moyen de la libérer, vous vous retrouverez dans une impasse. Utilisez des canaux ou l'annulation de contexte pour éviter cela.

  2. Utiliser select avec les canaux : lorsque vous travaillez avec plusieurs canaux, l'instruction select vous permet de gérer le canal qui est prêt en premier, évitant ainsi un blocage potentiel.

   select {
   case msg := <-channel1:
       fmt.Println("Received from channel1:", msg)
   case msg := <-channel2:
       fmt.Println("Received from channel2:", msg)
   default:
       fmt.Println("No data received")
   }
Copier après la connexion
  1. Fermer correctement les chaînes : La fermeture des chaînes signale qu'aucune donnée ne sera envoyée, ce qui est utile pour indiquer quand un Goroutine a fini d'envoyer des données.
   close(messageChannel)
Copier après la connexion
  1. Surveiller l'utilisation de la mémoire : Étant donné que les Goroutines sont si légères, il est facile d'en générer trop. Surveillez l'utilisation de la mémoire de votre application pour éviter de surcharger le système.

  2. Utiliser le contexte pour l'annulation : lorsque vous devez annuler les Goroutines, utilisez le package contextuel de Go pour propager les signaux d'annulation.

   ctx, cancel := context.WithCancel(context.Background())
   defer cancel()

   go func(ctx context.Context) {
       for {
           select {
           case <-ctx.Done():
               return
           default:
               // Continue processing
           }
       }
   }(ctx)
Copier après la connexion

Pensées finales

Les Goroutines sont une fonctionnalité puissante de Go, rendant la programmation simultanée accessible et efficace. En tirant parti des Goroutines, des WaitGroups et des canaux, vous pouvez créer des applications qui gèrent les tâches simultanément, évoluent efficacement et exploitent pleinement les processeurs multicœurs modernes.

試試看:在您自己的專案中嘗試 Goroutine!一旦掌握了它們的竅門,您就會發現它們為 Go 應用程式打開了一個充滿可能性的全新世界。快樂編碼! ?


您最喜歡的 Goroutine 用例是什麼? 請在評論中告訴我,或分享您有效使用 Goroutine 的任何其他技巧!

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!

source:dev.to
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal