2012-10-27 14 views
6

Kanał buforowy Go jest w istocie kolejką FIFO bezpieczną dla wątków. (Zobacz Is it possible to use Go's buffered channel as a thread-safe queue?)Czy buforowany kanał Is Go jest bez blokady?

Zastanawiam się, jak to jest realizowane. Czy jest on bezpieczny jak opisano w Is there such a thing as a lockless queue for multiple read or write threads??

greping w Go katalogu src (grep -r Lock .|grep chan) daje następujący wynik:

./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 

Nie należy blokowania na moim komputerze (MacOS Intel x86_64) chociaż. Czy jest jakiś oficjalny zasób, aby to potwierdzić?

Odpowiedz

6

Jeśli czytasz funkcję w chan.cruntime·chansend, widać że runtime·lock nazywa się przed sprawdzić, czy kanał jest buforowane if(c->dataqsiz > 0).

Innymi słowy, buforowane kanały (i wszystkie kanały w ogóle) używają blokad.

Przyczyna, dla której wyszukiwanie nie zostało znalezione, to było to, że szukałeś "Zablokuj" ze stolicą L. Funkcja blokady używana dla kanałów jest nie eksportowaną funkcją C w środowisku wykonawczym.

+0

Dzięki! Jakieś pomysły na temat tego, dlaczego nie są zaimplementowane jako wolne od blokady? –

+0

"Lockfree" nie oznacza lepszej wydajności. Łatwiej jest też wnioskować o blokadach. Metoda blokady jest prawdopodobnie szybsza, gdy występuje duża rywalizacja. –

+0

Dzięki, @ stephen-weinberg. Teraz ma to więcej sensu. –

3

Możesz pisać bez blokady (a nawet bezużyteczne!) Wdrożenia dla wszystkiego, co lubisz. Nowoczesne prymitywy sprzętowe, takie jak CMPXCHG, wystarczają do uniwersalnego zastosowania. Ale pisanie i weryfikacja takich algorytmów nie jest jednym z najłatwiejszych zadań. Oprócz tego mogą istnieć znacznie szybsze algorytmy: algorytmy typu "lock free" są po prostu bardzo małym podzbiorem algorytmów.

O ile pamiętam, Dmitry Vyukov napisał lock-free MPMC (mutli-producer/multi-consumer) implementację kanału dla Go w przeszłości, ale łatka została porzucona, z powodu pewnych problemów z instrukcją Go's select . Wspieranie tego oświadczenia sprawnie wydaje się być naprawdę trudne.

Głównym celem typu kanału Go jest zapewnienie prymitywu współbieżności wysokiego poziomu, który jest łatwy do zastosowania w szerokim zakresie problemów. Nawet programiści, którzy nie są ekspertami w programowaniu współbieżnym, powinni umieć pisać poprawne programy, które można łatwo przeglądać i utrzymywać w większych projektach oprogramowania. Jeśli jesteś zainteresowany wyciśnięciem każdej najmniejszej wydajności, musisz napisać specjalistyczną implementację kolejki, która będzie pasować do twoich potrzeb.

Powiązane problemy