Maison  >  Article  >  développement back-end  >  Comment utiliser le langage Go pour la programmation simultanée ?

Comment utiliser le langage Go pour la programmation simultanée ?

PHPz
PHPzoriginal
2023-06-10 10:33:07904parcourir

Avec le développement continu du matériel informatique, les cœurs CPU du processeur n'augmentent plus la fréquence d'horloge individuellement, mais augmentent le nombre de cœurs. Cela soulève une question évidente : comment tirer le meilleur parti de ces cœurs ?

Une solution consiste à utiliser la programmation parallèle, qui consiste à exécuter plusieurs tâches en même temps pour utiliser pleinement les cœurs du processeur. C'est une particularité du langage Go, c'est un langage conçu pour la programmation simultanée.

Dans cet article, nous explorerons comment utiliser le langage Go pour la programmation simultanée.

Coroutine

Tout d'abord, ce que nous devons comprendre est un mécanisme spécial dans le langage Go : la coroutine. Coroutine est un thread léger qui peut changer d'exécution plusieurs fois dans un seul thread pour réaliser une exécution parallèle.

Par rapport aux threads du système d'exploitation, le coût de commutation des coroutines est très faible. Ils sont gérés par le runtime Go, qui utilise un mappage m:n pour mapper m coroutines sur n threads du système d'exploitation. Cela rend le langage Go très efficace et stable en termes de capacités d'exécution simultanées.

En langage Go, vous pouvez utiliser le mot-clé go pour démarrer une coroutine. Par exemple : go 关键字来启动一个协程。例如:

func main() {
    go hello()
}

func hello() {
    fmt.Println("Hello, world!")
}

在上面的代码中,hello() 函数将在一个新的协程中执行。当程序退出 main() 函数时,hello() 函数可能还在执行,因此程序不会立即退出。

通道

协程之间的通信非常重要,因为它们需要共享数据。Go 语言中有一种特殊类型的变量,称为通道(Channel),用于在协程之间传递数据。

可以通过 make() 函数创建一个通道,例如:

ch := make(chan int)

上面的代码将创建一个整数类型的通道。

数据可以通过通道的发送和接收操作进行传递。可以使用 <- 运算符对通道进行发送和接收操作。例如:

ch <- 42 // 发送数据
x := <-ch // 接收数据

<- 运算符可以在左侧或右侧使用,以用于发送或接收数据。如果通道是无缓冲的,则发送操作将阻塞,直到另一个协程接收数据。类似地,如果没有可用的数据,则接收操作将阻塞。

WaitGroup

在处理多个协程时,可能需要等待它们全部执行完毕。可以使用 sync.WaitGroup 来实现这个目的。例如:

func main() {
    var wg sync.WaitGroup
    wg.Add(2) // 增加计数器

    go func() {
        defer wg.Done() // 完成时减少计数器
        fmt.Println("Hello,")
    }()

    go func() {
        defer wg.Done() // 完成时减少计数器
        fmt.Println("world!")
    }()

    wg.Wait() // 等待协程全部完成
}

在上面的代码中,wg 是一个 sync.WaitGroup 对象,包含一个计数器。Add() 方法将计数器增加,表示需要等待的协程数。Done() 方法将计数器减少,表示一个协程已经完成。Wait() 方法将一直等待,直到计数器为零。

例子

下面是一个示例程序,演示了如何利用协程和通道进行并发编程:

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

    go func() {
        for i := 0; i < 10; i++ {
            ch <- i // 发送数据
        }
        close(ch) // 关闭通道
    }()

    for i := range ch { // 循环接收数据,直到通道关闭
        fmt.Println(i)
    }
}

在上面的代码中,我们创建了一个整数类型的通道 ch。然后,我们在一个新的协程中向通道发送 0 到 9 的整数。最后,我们使用 range 关键字循环接收通道中的数据,并打印出来。

注意,我们在发送完所有数据后,通过 close() 方法关闭了通道。这使得循环读取通道的协程可以退出。

结论

在本文中,我们了解了 Go 语言中的协程、通道和 WaitGrouprrreee

Dans le code ci-dessus, la fonction hello() sera exécutée dans une nouvelle coroutine. Lorsque le programme quitte la fonction main(), la fonction hello() peut toujours être en cours d'exécution, donc le programme ne se terminera pas immédiatement. 🎜🎜Canaux🎜🎜La communication entre les coroutines est très importante car elles doivent partager des données. Il existe un type spécial de variable dans le langage Go appelé canal, qui est utilisé pour transférer des données entre coroutines. 🎜🎜Vous pouvez créer un canal via la fonction make(), par exemple : 🎜rrreee🎜Le code ci-dessus créera un canal de type entier. 🎜🎜Les données peuvent être transmises via les opérations d'envoi et de réception du canal. Les chaînes peuvent être envoyées et reçues à l'aide de l'opérateur <-. Par exemple : 🎜rrreee🎜<- Les opérateurs peuvent être utilisés sur le côté gauche ou droit pour envoyer ou recevoir des données. Si le canal n'est pas tamponné, l'opération d'envoi se bloquera jusqu'à ce qu'une autre coroutine reçoive les données. De même, si aucune donnée n'est disponible, l'opération de réception sera bloquée. 🎜🎜WaitGroup🎜🎜Lors du traitement de plusieurs coroutines, vous devrez peut-être attendre qu'elles terminent toutes leur exécution. Vous pouvez utiliser sync.WaitGroup à cet effet. Par exemple : 🎜rrreee🎜Dans le code ci-dessus, wg est un objet sync.WaitGroup qui contient un compteur. La méthode Add() augmente le compteur, indiquant le nombre de coroutines qui doivent attendre. La méthode Done() décrémente le compteur pour indiquer qu'une coroutine est terminée. La méthode Wait() attendra que le compteur atteigne zéro. 🎜🎜Exemple🎜🎜Voici un exemple de programme qui montre comment exploiter les coroutines et les canaux pour la programmation simultanée : 🎜rrreee🎜Dans le code ci-dessus, nous créons un canal de type entier ch. Nous envoyons ensuite des entiers de 0 à 9 au canal dans une nouvelle coroutine. Enfin, nous utilisons le mot-clé range pour parcourir les données du canal et les imprimer. 🎜🎜Notez que nous avons fermé le canal via la méthode close() après avoir envoyé toutes les données. Cela permet à la coroutine qui boucle pour lire le canal de quitter. 🎜🎜Conclusion🎜🎜Dans cet article, nous avons découvert les coroutines, les canaux et les WaitGroup dans le langage Go. Grâce à ces mécanismes, une programmation simultanée efficace peut être facilement mise en œuvre. Lorsque vous écrivez du code Go, veillez à envisager d'utiliser ces mécanismes pour utiliser pleinement les cœurs de processeur et les ressources matérielles. 🎜

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