Ich habe eine Funktion, die eine Goroutine erstellt, die einen Kanal auf unbestimmte Zeit füllt, zum Beispiel:
func foo() <-chan int { ch := make(chan int) go func() { defer close(ch) for { ch <- 1 } }() return ch }
Angenommen, wir haben einen Verbraucher, den wir nach einer bestimmten Zeit stoppen möchten:
ch:=foo() <-ch <-ch // done
Jetzt möchte ich Goroutine-Ressourcen bereinigen, einschließlich Kanälen. Ich habe versucht, dafür einen „Abschluss“-Kanal hinzuzufügen, bin dann aber in eine Sackgasse geraten:
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 }
Jetzt scheint es zu funktionieren, aber nur, weil das Programm beendet wird, wenn ich es durch einige io-Operationen ersetze // here
(例如:http.get(“http://google.com”)
) ,我面临死锁(fatal 错误:所有 goroutine 都在睡觉 - 死锁!
).
Ich frage mich, ob es eine andere Möglichkeit gibt, die von der Funktion foo
generierten Goroutinen und Kanäle zu bereinigen. foo
函数创建的生成的 goroutine 和通道。
只需在启动的 goroutine 中将 default
替换为 case
default
Ersetzen Sie einfach
case
in der Start-Goroutine: 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
-Situation blockiert ist, ist wie folgt: ch
读取两次。这会导致在启动的 goroutine 处有两个成功的执行循环。然后它尝试写入 done
。此时启动的goroutine可能已经检查了select
语句,陷入default
情况并阻塞在ch <- 1
行。因此主 goroutine 也会无限期地阻塞在 done <- true
Eine Goroutine, die das Schreiben in einen ch
-Kanal initiiert hat, geht sofort in den done
-Kanal schreiben. Die Goroutine blockiert dann die Zeile ch <- 1
, bis eine andere Goroutine den Wert von ch
liest.
🎜Die Hauptcoroutine liest zweimal aus ch
. Dies führt zu zwei erfolgreichen Ausführungsschleifen bei der gestarteten Goroutine. Anschließend wird versucht, done
zu schreiben. Die zu diesem Zeitpunkt gestartete Goroutine hat möglicherweise die select
-Anweisung überprüft, ist in die 🎜-Situation geraten und hat an der Zeile ch <- 1
blockiert. Daher blockiert die Haupt-Goroutine auch auf unbestimmte Zeit die Zeile done <- true
. Dies kann zu einem Deadlock führen. 🎜
🎜Das obige ist der detaillierte Inhalt vonStoppen Sie eine Goroutine, die auf unbestimmte Zeit in einen Kanal schreibt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!