Betrachten Sie das Spielzeugbeispiel unten. Der Code funktioniert tadellos, aber wenn Sie die 2 Linien austauschen, die als replace
markiert werden, gibt es einen Deadlock. Gibt es einen besseren Weg, mit einer solchen Situation umzugehen, wenn Sie eine unterschiedliche Anzahl von Sends und Empfängern haben?Golang Kanäle, die sich mit Senden befassen! = Erhalten
package main
import "fmt"
import "strconv"
func main() {
a := make(chan string)
b := make(chan string)
go func() {
for i := 0; i < 2; i++ {
go func(i int) {
fmt.Println(<-a)
b <- strconv.Itoa(i) + "b" // replace
a <- strconv.Itoa(i) + "a" // replace
}(i)
}
}()
a <- "0"
for i := 0; i < 2; i++ {
fmt.Println(<-b)
}
}
EDIT: eine select-Anweisung verwendet wird, gibt es eine Chance, dass a
wird durch die Auswahl und es gibt immer noch keine Möglichkeit, einen Stillstand zu verhindern abgeholt, weil die goroutines nicht
package main
import "fmt"
import "strconv"
func main() {
a := make(chan string)
b := make(chan string)
c := make(chan bool)
cancel := make(chan bool)
go func() {
for i := 0; i < 2; i++ {
go func(i int) {
fmt.Println(<-a)
b <- strconv.Itoa(i) + "b" // replace
a <- strconv.Itoa(i) + "a" // replace
c <- true
}(i)
}
}()
go func() {
<-c
<-c
cancel <- true
}()
a <- "0"
loop:
for {
select {
case ain := <-a:
fmt.Println("select", ain)
case bin := <-b:
fmt.Println("select", bin)
case <-cancel:
break loop
}
}
}
Wo schlägst du vor, dass ich das ... Mein Beispiel ist nur eine Vereinfachung, '<-a' und' <-b' müssen sein, wo ich sie in den Code einfüge. Denke nicht, dass ich ihre Standorte ändern kann. – tushar
Mit deinem Code aktualisiert. Ihr Originalcode macht keinen Sinn, da kein aktuelles Programm so geschrieben werden kann. Sie wollen immer den Empfänger des Kanals sperren, Punkt. Wenn Sie mehr als einen Kanal haben, benötigen Sie ein 'select', um an der ersten Eingabe zu blockieren. Wenn Sie mehrere Eingaben haben, wickeln Sie die Auswahl in eine for-Schleife. – eduncan911
Klingt wie B ist der Fall "Abbrechen" in meinem Beispiel. ;) – eduncan911