Maison >développement back-end >Golang >Comment utiliser les coroutines dans Go ?

Comment utiliser les coroutines dans Go ?

王林
王林original
2023-05-11 15:31:422405parcourir

Avec le développement de la technologie Internet, les exigences en matière de multitâche efficace sont de plus en plus élevées. Dans le langage Go, les coroutines sont une fonctionnalité très importante qui peut très bien résoudre ce problème. Cet article explique comment utiliser les coroutines pour implémenter la programmation simultanée dans Go.

1. Qu'est-ce qu'une coroutine ? Une coroutine est un thread léger, également appelé thread en mode utilisateur. Par rapport à la programmation multithread traditionnelle, les avantages des coroutines sont qu'elles sont plus légères, occupent moins de ressources système, changent de contexte plus rapidement et n'ont pas besoin de gérer des problèmes de sécurité des threads tels que des verrous comme la programmation multithread. Dans le langage Go, la coroutine est implémentée à l'aide de Goroutine.

2. Créer et démarrer une coroutine

En langage Go, vous pouvez utiliser l'instruction go pour démarrer une coroutine. L'instruction go est suivie d'un appel de fonction, qui démarre une nouvelle coroutine pour exécuter la fonction.

Par exemple :

func main() {
    go printHello()  // 启动一个goroutine去执行printHello函数
    fmt.Println("main function")
}

func printHello() {
    fmt.Println("hello goroutine")
}

Dans le code ci-dessus, nous utilisons l'instruction go pour démarrer une nouvelle coroutine afin d'exécuter la fonction printHello. La fonction printHello sera exécutée dans la nouvelle coroutine sans bloquer le thread principal. Une fois la fonction principale exécutée, le programme ne se terminera pas immédiatement car la fonction printHello est toujours en cours d'exécution.

3. Communication des coroutines

Dans les coroutines, puisque la mémoire est partagée entre différentes coroutines, des problèmes de communication entre plusieurs coroutines seront impliqués. Le langage Go fournit des canaux pour implémenter la communication entre les coroutines. La méthode de communication basée sur les canaux est une méthode de communication très efficace et sûre.

1. Définition et initialisation du canal

En langage Go, vous pouvez utiliser la fonction make pour créer un canal. La syntaxe est :

channel_name := make(chan data_type)

Parmi eux, data_type est le type de données transmises dans le canal. Par exemple, dans le code suivant, nous créons un canal qui transmet des données de type int :

ch := make(chan int)

2 Lecture et écriture du canal

Le canal peut effectuer à la fois des opérations d'envoi et de réception. Les opérations d'envoi et de réception sont bloquantes.

Opération d'envoi : utilisez l'opérateur <- du canal pour effectuer l'opération d'envoi, c'est-à-dire :
  • channel_name <- value
  • où valeur est la valeur à envoyer. Par exemple, dans le code suivant, nous envoyons la valeur 1 au canal nommé ch :
ch <- 1  // 向ch中发送数值1

Opération de réception : Utilisez l'opérateur <- du canal pour effectuer l'opération de réception, c'est-à-dire :
  • value := <- channel_name
  • où, la valeur est la valeur reçue. Par exemple, dans le code suivant, nous recevons une valeur du canal nommé ch et l'attribuons à la variable x :
x := <- ch  // 从ch中接收一个数值,并将其赋值给变量x

Il est à noter que s'il n'y a pas de données dans le canal à recevoir, l'opération de réception bloquera automatiquement jusqu'à ce que les données soient disponibles pour la réception. De même, si le canal est plein, l'opération d'envoi se bloquera jusqu'à ce qu'il y ait suffisamment d'espace pour envoyer.

4. Utilisez plusieurs coroutines pour communiquer

Ce qui suit est un exemple simple dans lequel deux coroutines sont créées, l'une envoie des données au canal et l'autre reçoit des données du canal. La communication des données entre ces deux coroutines s'effectue via des canaux :

func main() {
    ch := make(chan int)
    go producer(ch)
    go consumer(ch)
    time.Sleep(1 * time.Second)
}

func producer(ch chan int) {
    for i := 0; i < 5; i++ {
        ch <- i
    }
}

func consumer(ch chan int) {
    for i := range ch {
        fmt.Println("received:", i)
    }
}

Dans le code ci-dessus, la coroutine productrice générera des valeurs et enverra des données au canal, tandis que la coroutine consommatrice recevra les données du canal et les imprimera. Dans la fonction principale, nous démarrons respectivement les coroutines producteur et consommateur via l'instruction go. En raison de la nature bloquante du canal, les coroutines productrices et consommatrices peuvent communiquer en toute sécurité sans se soucier de l'incohérence des données.

4. Synchronisation des coroutines

Dans la programmation multi-coroutines, vous devez parfois attendre que d'autres coroutines se terminent avant d'effectuer certaines opérations. Dans ce cas, vous devez utiliser la technologie de synchronisation coroutine.

Le langage Go fournit un package Sync, qui contient quelques outils de base pour la synchronisation des coroutines :

WaitGroup : attendez qu'un groupe de coroutines se termine avant d'effectuer une opération.
  • Mutex : verrouillage Mutex pour empêcher plusieurs coroutines de fonctionner sur les mêmes données en même temps.
  • Cond : variable de condition, permettant à une coroutine d'attendre qu'une certaine condition soit satisfaite avant d'effectuer l'opération suivante.
  • Ici, nous prenons WaitGroup comme exemple pour présenter l'implémentation de la synchronisation des coroutines.

1. Définition et initialisation de WaitGroup

Avant d'utiliser WaitGroup, vous devez utiliser la méthode Add pour ajouter le nombre de coroutines à attendre dans WaitGroup. Par exemple :

var wg sync.WaitGroup
wg.Add(2)

Dans le code ci-dessus, nous avons ajouté deux coroutines à WaitGroup.

2. Appelez la méthode Done une fois l'exécution de la coroutine terminée

Une fois l'exécution de la coroutine terminée, la méthode Done de WaitGroup doit être appelée, indiquant que l'exécution d'une coroutine est terminée, par exemple :

go func() {
    defer wg.Done()  // 协程执行完成后调用Done方法
    ...
}()

Dans le code ci-dessus, nous Une coroutine est ajoutée au WaitGroup et la méthode Done est appelée une fois l'exécution de la coroutine terminée.

3. Attendez que l'exécution de toutes les coroutines soit terminée

Après avoir ajouté toutes les coroutines qui doivent être attendues dans le WaitGroup, utilisez la méthode Wait pour attendre la fin de l'exécution de toutes les coroutines. Par exemple :

wg.Wait()  // 等待所有协程执行完成

Dans le code ci-dessus, nous utilisons la méthode Wait pour attendre la fin de l'exécution de toutes les coroutines. La méthode Wait bloque la goroutine principale jusqu'à ce que toutes les coroutines soient exécutées.

5. Résumé

Cet article présente l'utilisation des coroutines dans le langage Go, y compris la création et le démarrage de coroutines, la communication entre coroutines, la synchronisation des coroutines, etc. Les coroutines sont une fonctionnalité très importante du langage Go et jouent un rôle très important dans la programmation multitâche et à haute concurrence. L'utilisation de coroutines peut rendre les programmes plus efficaces et plus stables, et également permettre aux développeurs d'effectuer une programmation simultanée.

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:
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