Maison  >  Article  >  développement back-end  >  Modes de concurrence dans Golang : canaux et pipelines

Modes de concurrence dans Golang : canaux et pipelines

王林
王林original
2023-08-09 10:05:051463parcourir

Golang 中的并发模式之 Channels 和 Pipelines

Modes simultanés dans Golang : canaux et pipelines

Dans Golang, nous pouvons utiliser goroutine pour implémenter la programmation simultanée. Dans le développement réel, nous devons souvent gérer le flux de données de tâches simultanées. Golang propose deux modes de concurrence, canaux et pipelines, pour gérer cette situation.

Les canaux sont une primitive de concurrence très puissante dans Golang, utilisée pour transmettre des données entre goroutines. Il assure la synchronisation et la livraison sécurisée des données. En envoyant et en recevant des données sur un canal, nous assurons l'ordre et la synchronisation entre les goroutines.

Pipelines est un modèle de concurrence qui traite le flux de données en connectant plusieurs goroutines. Chaque goroutine possède des canaux d'entrée et de sortie, et en les chaînant, les données peuvent circuler et être traitées entre toutes les goroutines.

Tout d’abord, examinons l’utilisation de base des chaînes. Dans Golang, vous pouvez utiliser la fonction make() pour créer un canal.

ch := make(chan int)

Nous pouvons utiliser l'opérateur <- pour envoyer des données au canal, par exemple : <- 操作符将数据发送到 channel 中,例如:

ch <- 10

并且使用 <- 操作符从 channel 中接收数据,例如:

x := <-ch

请注意,接收操作将被阻塞,直到有数据可用。而发送操作也会被阻塞,直到有其他 goroutine 准备好接收数据。

下面是一个简单的示例,使用一个 channel 将生成的随机数发送到另一个 goroutine 中:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    ch := make(chan int)

    go randomGenerator(ch) // 启动生成随机数的 goroutine

    // 等待接收随机数并打印
    for i := 0; i < 10; i++ {
        num := <-ch
        fmt.Println("Received random number:", num)
        time.Sleep(1 * time.Second)
    }
}

func randomGenerator(ch chan int) {
    for {
        // 生成随机数并发送到 channel
        num := rand.Intn(100)
        ch <- num
    }
}

在上面的示例中,我们通过 randomGenerator() 函数生成随机数,并将其发送到 ch channel 中。main 函数则从 channel 中接收随机数并打印。

接下来,让我们来介绍一下 pipelines 的并发模式。一个 pipeline 包含多个 goroutine,通过将它们串联在一起,可以构建一个处理数据流的网络。

假设我们有一个数字列表,我们想对列表中的每个数字进行平方操作,然后将结果打印出来。我们可以使用两个 goroutine 来实现这个功能:一个用于计算平方,另一个用于打印结果。

package main

import (
    "fmt"
)

func main() {
    numbers := []int{1, 2, 3, 4, 5}
    input := make(chan int)
    output := make(chan int)

    // 启动计算平方的 goroutine
    go square(input, output)

    // 启动打印结果的 goroutine
    go printer(output)

    // 将数字发送到 input channel
    for _, num := range numbers {
        input <- num
    }

    // 关闭 input channel,表示数据发送完毕
    close(input)

    // 等待所有结果被打印
    <-output
}

func square(input chan int, output chan int) {
    for num := range input {
        // 计算平方,并发送结果到 output channel
        result := num * num
        output <- result
    }

    // 关闭 output channel,表示计算完毕
    close(output)
}

func printer(output chan int) {
    for result := range output {
        // 打印结果
        fmt.Println("Result:", result)
    }

    // 发送信号表示输出完毕
    output <- 0
}

在上面的示例中,我们首先创建一个 input channel 和一个 output channel。然后我们启动了两个 goroutine:square() 用于计算平方操作,并将结果发送到 output channel,printer() 则从 output channel 中接收结果并打印。

main 函数中,我们使用 for 循环将数字发送到 input channel 中。然后我们关闭 input channel,表示数据发送完毕。最后我们等待从 outputrrreee

et utiliser l'opérateur <- pour recevoir des données du canal. canal, par exemple :

rrreee

Veuillez noter que l'opération de réception sera bloquée jusqu'à ce que les données soient disponibles. L'opération d'envoi sera également bloquée jusqu'à ce qu'un autre goroutine soit prêt à recevoir des données. 🎜🎜Ce qui suit est un exemple simple qui utilise un canal pour envoyer les nombres aléatoires générés à un autre goroutine : 🎜rrreee🎜Dans l'exemple ci-dessus, nous générons des nombres aléatoires via la fonction randomGenerator(), et envoyons vers le canal ch. La fonction principale reçoit des nombres aléatoires du canal et les imprime. 🎜🎜Ensuite, introduisons le mode de concurrence des pipelines. Un pipeline contient plusieurs goroutines, et en les mettant en cascade, un réseau peut être construit pour traiter le flux de données. 🎜🎜Supposons que nous ayons une liste de nombres et que nous voulions mettre chaque nombre au carré dans la liste, puis imprimer le résultat. Nous pouvons utiliser deux goroutines pour implémenter cette fonctionnalité : une pour calculer le carré et une autre pour imprimer le résultat. 🎜rrreee🎜Dans l'exemple ci-dessus, nous créons d'abord un canal input et un canal output. Ensuite nous avons démarré deux goroutines : square() est utilisé pour calculer l'opération carré et envoie le résultat au canal output, printer() puis Recevez les résultats du canal output et imprimez-les. 🎜🎜Dans la fonction main, nous utilisons une boucle for pour envoyer des nombres au canal input. Ensuite, nous fermons le canal input, indiquant que les données sont envoyées. Enfin nous attendons de recevoir un signal du canal output indiquant que tous les résultats ont été imprimés. 🎜🎜En utilisant des canaux et des pipelines, nous pouvons facilement mettre en œuvre un traitement simultané des flux de données. Ils fournissent à Golang un moyen puissant et concis de programmation simultanée, nous permettant de gérer efficacement les tâches simultanées. Qu'il s'agisse d'un simple transfert de données ou d'un réseau de traitement de données complexe, ces deux modes de concurrence peuvent nous aider à écrire des programmes concurrents efficaces et fiables. 🎜

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