Maison >développement back-end >Golang >Arrêtez indéfiniment une goroutine qui écrit sur un canal
J'ai une fonction qui crée une goroutine qui remplit un canal indéfiniment, par exemple :
func foo() <-chan int { ch := make(chan int) go func() { defer close(ch) for { ch <- 1 } }() return ch }
Supposons que nous ayons un consommateur que nous souhaitons arrêter après un certain temps :
ch:=foo() <-ch <-ch // done
Maintenant, je souhaite nettoyer les ressources goroutine, y compris les chaînes. J'ai essayé d'ajouter un canal « achèvement » pour cela, mais je me suis ensuite retrouvé dans une impasse :
func Foo() (<-chan int, chan<- bool) { ch := make(chan int) done := make(chan bool) go func() { defer close(ch) for { select { case <-done: return default: ch <- 1 } } }() return ch, done } func main() { ch, done := Foo() <-ch <-ch done <- true // HERE }
Maintenant, cela semble fonctionner, mais uniquement parce que le programme se termine si je le remplace par quelques opérations io // here
(例如:http.get(“http://google.com”)
) ,我面临死锁(fatal 错误:所有 goroutine 都在睡觉 - 死锁!
).
Je me demande s'il existe un autre moyen de nettoyer les goroutines et les canaux générés par la fonction foo
. foo
函数创建的生成的 goroutine 和通道。
只需在启动的 goroutine 中将 default
替换为 case
default
Remplacez simplement
case
dans la goroutine de départ : func Foo() (<-chan int, chan<- bool) { ch := make(chan int) done := make(chan bool) go func() { defer close(ch) for { select { case <-done: return case ch <- 1: } } }() return ch, done }
done
通道时,启动的写入 ch
通道的 goroutines 会立即转到 default
情况。然后 goroutine 会阻塞在 ch <- 1
行,直到其他 goroutine 从 ch
est la suivante : ch
读取两次。这会导致在启动的 goroutine 处有两个成功的执行循环。然后它尝试写入 done
。此时启动的goroutine可能已经检查了select
语句,陷入default
情况并阻塞在ch <- 1
行。因此主 goroutine 也会无限期地阻塞在 done <- true
Une goroutine initiée en train d'écrire sur un canal ch
ira immédiatement au cas done
. La goroutine bloquera alors sur la ligne ch <- 1
jusqu'à ce qu'une autre goroutine lise la valeur de ch
.
🎜La coroutine principale lit deux fois depuis ch
. Cela se traduit par deux boucles d'exécution réussies au niveau de la goroutine lancée. Il tente ensuite d'écrire done
. La goroutine démarrée à ce moment-là a peut-être vérifié l'instruction select
, est tombée dans la situation 🎜 et s'est bloquée sur la ligne ch <- 1
. Par conséquent, la goroutine principale bloquera également indéfiniment sur la ligne done <- true
. Cela peut conduire à une impasse. 🎜
🎜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!