Comment implémenter plusieurs coroutines pour lire et écrire les mêmes canaux en même temps dans Golang
Dans la programmation Go, les goroutines sont largement utilisées pour obtenir la concurrence et le parallélisme. Les canaux sont une structure de données spéciale utilisée pour la communication et la synchronisation entre les coroutines. Les canaux offrent un moyen sûr de partager des données entre coroutines.
Dans certains cas, nous pouvons avoir besoin de plusieurs coroutines pour lire ou écrire le même canal en même temps. Étant donné que Channel se bloque par défaut, si des mesures spéciales ne sont pas prises, plusieurs coroutines se bloqueront mutuellement, empêchant le programme de fonctionner normalement. Ensuite, je couvrirai deux solutions courantes.
Solution 1 : Utiliser un canal tamponné
Le canal tamponné est un canal à capacité limitée. Lors de la création d'un Channel, nous pouvons préciser sa capacité. Lorsque le tampon du canal n'est pas plein, les opérations d'écriture peuvent se terminer immédiatement ; lorsque le tampon n'est pas vide, les opérations de lecture peuvent également se terminer immédiatement. Les opérations de lecture et d'écriture se bloquent uniquement lorsque le tampon est plein ou vide.
Ce qui suit est un exemple de code :
package main import ( "fmt" "time" ) func main() { // 创建一个容量为1的缓冲 Channel ch := make(chan int, 1) // 启动多个协程,并同时写入 Channel for i := 1; i <= 5; i++ { go func(i int) { ch <- i fmt.Printf("协程 %d 写入数据 ", i) }(i) } // 读取 Channel 中的数据 time.Sleep(time.Second) // 休眠 1 秒,等待协程写入数据 for i := 1; i <= 5; i++ { fmt.Printf("读取到数据:%d ", <-ch) } }
Dans le code ci-dessus, nous créons un canal tampon ch
d'une capacité de 1. Ensuite, 5 coroutines sont démarrées et écrivent des données sur le canal ch
en même temps. Étant donné que le canal est mis en mémoire tampon, les écritures se terminent immédiatement. Enfin, nous parcourons les données du canal et effectuons des opérations de lecture. ch
。然后启动了 5 个协程,它们同时向 Channel ch
写入数据。由于 Channel 是缓冲的,所以写入操作可以立即完成。最后,我们遍历 Channel 中的数据,并进行读取操作。
解决方案二:使用带有 select 语句的无缓冲 Channel
无缓冲 Channel 是一种没有容量的 Channel。在这种情况下,读取和写入操作都会阻塞,直到有另一个协程执行相反的操作。但我们可以使用 select
语句来实现同时读写无缓冲 Channel,避免协程相互阻塞。
下面是一个示例代码:
package main import ( "fmt" "time" ) func main() { // 创建无缓冲 Channel ch := make(chan int) // 启动多个协程,并同时写入 Channel for i := 1; i <= 5; i++ { go func(i int) { select { case ch <- i: fmt.Printf("协程 %d 写入数据 ", i) default: fmt.Printf("协程 %d 无法写入数据 ", i) } }(i) } // 读取 Channel 中的数据 time.Sleep(time.Second) // 休眠 1 秒,等待协程写入数据 for i := 1; i <= 5; i++ { select { case data := <-ch: fmt.Printf("读取到数据:%d ", data) default: fmt.Println("无法读取数据") } } }
上述代码中,我们创建了一个无缓冲 Channel ch
。与解决方案一不同的是,在写入数据时我们使用了 select
语句,并在 case
中处理写入成功和失败的情况。相同地,在读取数据时我们也使用了 select
select
pour lire et écrire simultanément un canal sans tampon afin d'éviter que les coroutines ne se bloquent mutuellement. Voici un exemple de code : rrreee
Dans le code ci-dessus, nous créons un canalch
sans tampon. La différence avec la première solution est que nous utilisons l'instruction select
lors de l'écriture des données et gérons le succès et l'échec de l'écriture dans case
. De même, nous utilisons également l'instruction select
lors de la lecture de données pour gérer la situation dans laquelle les données ne peuvent pas être lues. 🎜🎜Résumé : 🎜🎜En utilisant un canal tamponné ou un canal non tamponné avec une instruction select, nous pouvons obtenir plusieurs coroutines lisant et écrivant le même canal en même temps. Ces solutions peuvent améliorer l'efficacité de votre programme et éviter que les coroutines ne se bloquent les unes les autres. 🎜🎜Bien sûr, en plus des solutions ci-dessus, il existe d'autres techniques de programmation simultanée plus avancées, comme l'utilisation de WaitGroup, Mutex, etc. Dans les applications réelles, nous devons choisir un mécanisme de contrôle de concurrence approprié en fonction de besoins spécifiques. J'espère que cet article pourra vous aider à mieux comprendre et appliquer la programmation simultanée dans Golang. 🎜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!