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

Le mécanisme de blocage du Buffered Channel de Go

WBOY
Libérer: 2024-02-10 14:30:11
avant
1023 Les gens l'ont consulté

Go 的 Buffered Channel 的阻塞机制

Dans le langage Go, il existe un type de canal spécial appelé Buffered Channel, qui stocke un certain nombre d'éléments dans le canal. Lorsque le nombre d'éléments dans le canal atteint la limite supérieure définie, l'opération d'écriture sera bloquée jusqu'à ce que d'autres coroutines lisent les éléments du canal. Au contraire, lorsque le nombre d'éléments dans le canal est nul, l'opération de lecture sera également bloquée jusqu'à ce qu'une autre coroutine écrive des éléments dans le canal. Ce mécanisme de blocage peut contrôler efficacement la synchronisation et la communication entre les coroutines. Dans cet article, nous présenterons en détail le mécanisme de blocage de Buffered Channel dans le langage Go.

Contenu de la question

Dans "Tour of Go", l'exemple de code est donné comme ceci :

package main

import "fmt"

func main() {
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}
Copier après la connexion

Il s'exécute bien et s'imprime

1
2
Copier après la connexion

Ce comportement diffère de la description de cet exercice, qui indique :

<code>
Sends to a buffered channel block only when the buffer is full. Receives block when the buffer is empty
</code>
Copier après la connexion

dans ch <- 2 行之后,ch is 已满,并且由于我们只运行 1 个单独的 Goroutine,即主 Goroutine,因此该 Goroutine 应该被阻塞,直到 ch is 被接收者消耗,因此代码不应该到达fmt.Println(<-ch) OK, mais je devrais dire quelque chose comme

<code>
fatal error: all goroutines are asleep - deadlock!
</code>
Copier après la connexion

Cependant, comme ce n'est pas le cas, je suis confus et je cherche des conseils.

C'est un autre morceau de code que j'ai écrit

chh := make(chan int, 2)

go func() {
    chh <- 1
    fmt.Printf("chh after 1: %v, %v\n", cap(chh), len(chh))
    chh <- 2
    fmt.Printf("chh after 2: %v, %v\n", cap(chh), len(chh))
    chh <- 3
    fmt.Printf("chh after 3: %v, %v\n", cap(chh), len(chh))
}()

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

Le résultat de l'exécution est

1
chh after 1: 2, 0
chh after 2: 2, 0
chh after 3: 2, 1
2
3
Copier après la connexion

C'est encore plus déroutant. Cette fois, c'est un autre goroutine qui effectue l'envoi. Je m'attends à ce qu'il soit bloqué immédiatement après le premier fmt.Println(<-chh) 期间,主 goroutine 应该被阻塞。调度程序将选择运行匿名函数的 goroutine,并且它应该执行到 chh <- 2,然后它会阻塞自身,调度程序再次恢复到主 goroutine。然而,如结果所示,第二个 goroutine 在 chh <- 1. Pourquoi cela arrive-t-il?

Edit : Je ne comprends toujours pas pourquoi mon local imprime 1 en premier lieu. Lorsque j'essaie d'utiliser go Playground sur le serveur distant, il affiche un comportement différent, désormais conforme à mes attentes.

On sait que le canal est composé de 3 files d'attente (réception des goroutines, envoi des goroutines et tampon de valeurs). Lorsque la fonction anonyme s'exécute, le canal chh的状态为(sending:empty,valuebuffer:empty,receiving:[main] ).

Le Goroutine enfant en cours d'exécution pousse simplement la valeur directement dans le Goroutine principal sans réellement la transmettre au tampon de valeur. C'est pourquoi chh推送后1的长度是0.

Solution

Cette chaîne peut accueillir deux personnes. Deux envois peuvent réussir sans blocage. Le troisièmene peut pas. Les envois ne seront bloqués que si la chaîne est pleine avant l'envoi.

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!

Étiquettes associées:
source:stackoverflow.com
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!