Ich bin in einer seltsamen Situation fest, wo die Schreiboperation auf den Kanal nie passiert.Schreiben auf Kanal blockiert für immer
package main
import (
"fmt"
"time"
)
func main() {
c := make(chan int)
s := make(chan bool)
k := make(chan bool)
fmt.Println("start")
go func() {
fmt.Println("routine 1")
s <- true
}()
go func() {
fmt.Println("routine 2")
for {
select {
case <-s :
for i := 0; i < 3; i++ {
fmt.Println("before")
c <- i
fmt.Println("after")
}
case <- k :
fmt.Println("k ready")
break
}
}
}()
go func() {
fmt.Println("routine 3")
for {
select {
case x := <- c :
fmt.Println("x=", x)
k <- true
fmt.Println("k done")
}
}
}()
time.Sleep(1000 * time.Millisecond)
}
Und hier ist die Ausgabe:
start
routine 1
routine 2
before
routine 3
x= 0
after
before
Ich frage mich, warum das Schreiben in den Kanal k Blöcke, aber die Log-Anweisung fmt.Println("k ready")
nie gedruckt wird. Hier
ist, was ich denke:
- gehen Routine 1 schreibt wahr Kanal s
- gehen Routine 2 0 bis Kanal c schreibt und wartet, weil Puffergröße 0 ist, wird es nicht möglich sein, Schreiben Sie '1' zu ihm, es sei denn, jemand liest Kanal c
- gehen Routine 3 kommt in das Bild, liest Kanal c (jetzt gehen Routine 2 kann schreiben c einmal gehen Routine 2 setzt fort) druckt den Wert von x. Jetzt sollte es MÖGLICH ZU KANAL K zu schreiben, aber das geschieht nicht
mich nach ihm zu Kanal k dann Fall 2 von goroutine schreiben können sollten ausführen soll und print „k ready“
Kann mir jemand erklären, warum auf den blockierten Kanal schreiben? Als Fix weiß ich, ich kann die Puffergröße von Kanal c erhöhen und alles wird gedruckt, aber ich bin nicht daran interessiert, dies zu beheben, stattdessen möchte ich dieses Szenario verstehen.
Eine nette blog, um den obigen Fall zu verstehen.
Link zu obigen Code ist [hier] (https://play.golang.org/p/3YL2eoTVn1) –