php-Editor Baicao beantwortet in diesem Artikel eine häufig gestellte Frage: „Was ist der Grund für einen Deadlock im Go-Code mit WaitGroups und Buffered Channels?“ In der Go-Sprache sind WaitGroups und Buffered Channels häufig verwendete Tools für die gleichzeitige Programmierung. Manchmal kann es jedoch im Code, der sie verwendet, zu Deadlock-Situationen kommen. In diesem Artikel werden die Ursachen von Deadlocks untersucht und Lösungen bereitgestellt, die den Lesern helfen, dieses Problem zu vermeiden. Egal, ob Sie Anfänger oder erfahrener Go-Entwickler sind, dieser Artikel liefert Ihnen wertvolle Informationen.
Wartegruppen, Pufferkanäle und Deadlocks
Dieser Code von mir verursacht einen Deadlock, aber ich bin mir nicht sicher, warum. Ich habe versucht, Mutexe an verschiedenen Stellen zu verwenden und Kanäle innerhalb und außerhalb separater Go-Routinen zu schließen, aber immer noch das gleiche Ergebnis.
Ich versuche, Daten über einen Kanal (Inputchan) zu senden und dann Daten von einem anderen Kanal (Outputchan) zu lesen
package main import ( "fmt" "sync" ) func listStuff(wg *sync.WaitGroup, workerID int, inputChan chan int, outputChan chan int) { defer wg.Done() for i := range inputChan { fmt.Println("sending ", i) outputChan <- i } } func List(workers int) ([]int, error) { _output := make([]int, 0) inputChan := make(chan int, 1000) outputChan := make(chan int, 1000) var wg sync.WaitGroup wg.Add(workers) fmt.Printf("+++ Spinning up %v workers\n", workers) for i := 0; i < workers; i++ { go listStuff(&wg, i, inputChan, outputChan) } for i := 0; i < 3000; i++ { inputChan <- i } done := make(chan struct{}) go func() { close(done) close(inputChan) close(outputChan) wg.Wait() }() for o := range outputChan { fmt.Println("reading from channel...") _output = append(_output, o) } <-done fmt.Printf("+++ output len: %v\n", len(_output)) return _output, nil } func main() { List(5) }
Der Code in der Hauptfunktion ist kontinuierlich, Zuerstversuchen Sie, 3k Werte in inputchan
zu schreiben inputchan
然后将从 outputchan
Dann
outputchan</ Code>. <p>
</p>Ihr Code blockiert den ersten Schritt: <ul>
<li>
<code>inputchan
之前,outputchan
不会流失任何内容,因此工作人员最终会在第一个 1k 值之后卡在 outputchan <- i
Der Wert von 3.000 wurde erfolgreich an inputchan
中消耗资源,main
将在大约 2k 个值之后卡在 inputchan <- i
Sobald das Personal aufhört
inputchan <- i
) 和最终消费者 (for o := range outputchan {
Eine Möglichkeit, dieses Problem zu lösen, besteht darin, den Produzenten (
Sie können einen dieser Schauspieler in der Haupt-Goroutine behalten und einen neuen Schauspieler für den anderen einsetzen. Zum Beispiel:
go func(inputchan chan<- int){ for i := 0; i < 3000; i++ { inputchan <- i } close(inputchan) }(inputchan) done := make(chan struct{}) go func() { close(done) // close(inputchan) // i chose to close inputchan above, don't close it twice close(outputchan) wg.wait() }() ...
done
的操作顺序很重要;通道 done
和 outputchan
只能在 wg.done()
Eine zusätzliche Anmerkung: Surround-Signalisierung , um alle Mitarbeiter anzuweisen, zu schließen, wenn sie fertig sind
// it is best to close inputChan next to the code that controls // when its input is complete. close(inputChan) // If you had several producers writing to the same channel, you // would probably have to add a separate waitgroup to handle closing, // much like you did for your workers go func() { wg.Wait() // the two following actions must happen *after* workers have // completed close(done) close(outputChan) }()
Das obige ist der detaillierte Inhalt vonWas sind die Ursachen für Deadlocks im Go-Code, der WaitGroups und Buffered Channels verwendet?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!