2012-10-27 8 views
6

Gos gepufferter Kanal ist im Wesentlichen eine Thread-sichere FIFO-Warteschlange. (Siehe Is it possible to use Go's buffered channel as a thread-safe queue?)Ist der gepufferte Kanal von Go gesperrt?

Ich frage mich, wie es umgesetzt wird. Ist es wie in Is there such a thing as a lockless queue for multiple read or write threads? beschrieben sperrefrei?

in Gos src Verzeichnis greping (grep -r Lock .|grep chan) ergibt folgende Ausgabe:

./pkg/runtime/chan.c: Lock; 
./pkg/runtime/chan_test.go: m.Lock() 
./pkg/runtime/chan_test.go: m.Lock() // wait 
./pkg/sync/cond.go: L Locker // held while observing or changing the condition 

Hat auf meinem Rechner (MacOS, Intel x86_64), wenn auch nicht zu sperren. Gibt es eine offizielle Ressource, um dies zu bestätigen?

Antwort

6

Wenn Sie die runtime·chansend Funktion in chan.c lesen, werden Sie sehen, dass runtime·lock vor der Prüfung aufgerufen wird, um zu sehen, ob der Kanal if(c->dataqsiz > 0) gepuffert.

Mit anderen Worten, gepufferte Kanäle (und alle Kanäle im Allgemeinen) verwenden Sperren.

Der Grund, warum Ihre Suche nicht gefunden wurde, war, dass Sie nach "Lock" mit einem großen L gesucht haben. Die für Kanäle verwendete Sperrfunktion ist eine nicht exportierte C-Funktion in der Laufzeit.

+0

Danke! Irgendwelche Ideen darüber, warum es nicht als Lock-Free implementiert ist? –

+0

"Lockfree" bedeutet keine bessere Leistung. Es ist auch einfacher, über Sperren zu begründen. Die Lock-Methode ist wahrscheinlich schneller, wenn es zu hohen Konflikten kommt. –

+0

Danke, @ stephen-weinberg. Das macht jetzt mehr Sinn. –

3

Sie können lock-freie (und sogar wartefreie!) Implementierungen für alles, was Sie mögen, schreiben. Moderne Hardware-Primitive wie CMPXCHG reichen aus, um universell einsetzbar zu sein. Aber das Schreiben und Verifizieren solcher Algorithmen ist keine der einfachsten Aufgaben. Darüber hinaus können viel schnellere Algorithmen existieren: Lock-Free-Algorithmen sind nur eine sehr kleine Teilmenge von Algorithmen im Allgemeinen.

Soweit ich mich erinnere, hat Dmitry Vyukov in der Vergangenheit eine lock-freie MPMC (Multi-Producer/Multi-Consumer) -Kanal-Implementierung für Go geschrieben, aber der Patch wurde wegen einiger Probleme mit Gos Select-Anweisung aufgegeben . Diese Aussage effizient zu unterstützen, scheint sehr schwer zu sein.

Das Hauptziel von Go's Kanaltyp ist es jedoch, ein High-Level-Concurrency-Primitiv bereitzustellen, das für eine breite Palette von Problemen leicht verwendbar ist. Selbst Entwickler, die keine Experten für die gleichzeitige Programmierung sind, sollten in der Lage sein, korrekte Programme zu schreiben, die leicht in größeren Softwareprojekten überprüft und gewartet werden können. Wenn Sie daran interessiert sind, das letzte bisschen Leistung herauszuholen, müssten Sie eine spezielle Warteschlangenimplementierung schreiben, die Ihren Anforderungen entspricht.