Wie man richtig mit sync.Cond?

Ich habe Schwierigkeiten, herauszufinden, wie man richtig mit sync.Cond. Was ich sagen kann, existiert eine race condition zwischen sperren der Schrank und die Berufung auf die Bedingung der Wait-Methode. In diesem Beispiel wird eine künstliche Verzögerung zwischen den beiden Zeilen in der main-goroutine zu simulieren, die race-condition:

package main

import (
    "sync"
    "time"
)

func main() {
    m := sync.Mutex{}
    c := sync.NewCond(&m)
    go func() {
        time.Sleep(1 * time.Second)
        c.Broadcast()
    }()
    m.Lock()
    time.Sleep(2 * time.Second)
    c.Wait()
}

[Laufen auf den Spielplatz Gehen]

Dies bewirkt eine sofortige Panik:

fatal error: alle goroutines schlafen - deadlock! 

goroutine 1 [semacquire]: 
sync.runtime_Syncsemacquire(0x10330208, 0x1) 
/usr/local/go/src/runtime/sema.go:241 +0x2e0 
sync.(*Cond).Warten(0x10330200, 0x0) 
/usr/local/go/src/sync/cond.go:63 +0xe0 
main.main() 
/tmp/sandbox301865429/main.go:17 +0x1a0

Was mache ich falsch? Wie kann ich vermeiden, dass diese scheinbare race-condition? Gibt es eine bessere Synchronisation Konstrukt, das ich verwenden soll?


Edit: ich merke, ich sollte besser erklärt das problem, das ich zu lösen versuche hier. Ich habe eine lang andauernde goroutine lädt eine große Datei und eine Reihe von anderen goroutines, die Zugriff auf die HTTP-Header, wenn Sie verfügbar sind. Dieses problem ist schwieriger als es klingt.

Kann ich nicht die Kanäle, da nur eine goroutine würde dann den Wert. Und einige der anderen goroutines würde versuchen, rufen Sie die Header, lange nachdem Sie bereits verfügbar sind.

Den downloader goroutine könnte einfach speichern Sie die HTTP-Header in einer Variablen zu, und verwenden Sie einen mutex zum Schutz Zugang zu Ihnen. Dies bedeutet jedoch nicht, bieten eine Möglichkeit für die anderen goroutines "warten" für Sie verfügbar wird.

Ich hatte gedacht, dass beide eine sync.Mutex und sync.Cond zusammen erreichen könnten, dieses Ziel aber es scheint, dass dies nicht möglich ist.

InformationsquelleAutor Nathan Osman | 2016-04-26
Schreibe einen Kommentar