2012-10-27 9 views
6

Il canale buffer di Go è essenzialmente una coda FIFO thread-safe. (Vedi Is it possible to use Go's buffered channel as a thread-safe queue?)Il canale bufferizzato di Go è lockless?

Mi chiedo come sia implementato. È privo di blocco come descritto in Is there such a thing as a lockless queue for multiple read or write threads??

greping nella directory src del Go (grep -r Lock .|grep chan) fornisce output seguente:

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

non fa per essere di blocco sulla mia macchina (MacOS, Intel x86_64) però. C'è qualche risorsa ufficiale per convalidare questo?

risposta

6

Se leggete la funzione runtime·chansend in chan.c, si vedrà che runtime·lock è chiamato prima del controllo per vedere se il canale è tamponato if(c->dataqsiz > 0).

In altre parole, i canali bufferizzati (e tutti i canali in generale) utilizzano i blocchi.

Il motivo per cui la ricerca non è stato trovato era che cercavi "Blocca" con una S maiuscola. La funzione di blocco utilizzata per i canali è una funzione C non esportata nel runtime.

+0

Grazie! Qualche idea sul perché non è implementata come lock-free? –

+0

"Lockfree" non implica prestazioni migliori. È anche più facile ragionare sulle serrature. Il metodo di blocco è probabilmente più veloce in caso di contesa elevata. –

+0

Grazie, @ stephen-weinberg. Ciò ha più senso ora. –

3

È possibile scrivere implementazioni senza blocchi (e persino senza attendere!) Per tutto ciò che si desidera. I moderni primitivi hardware come CMPXCHG sono sufficienti per essere universalmente utilizzabili. Ma scrivere e verificare tali algoritmi non è uno dei compiti più facili. In aggiunta a ciò, potrebbero esistere algoritmi molto più veloci: gli algoritmi free lock sono solo un sottogruppo molto piccolo di algoritmi in generale.

Per quanto mi ricordo, Dmitry Vyukov ha scritto un'implementazione del canale MPMC (mutli-producer/multi-consumer) per Go in passato, ma la patch è stata abbandonata, a causa di alcuni problemi con l'istruzione select di Go . Supportare questa affermazione in modo efficiente sembra essere davvero difficile.

L'obiettivo principale del tipo di canale di Go è tuttavia quello di fornire un primitivo di concorrenza di alto livello che sia facilmente utilizzabile per una vasta gamma di problemi. Anche gli sviluppatori che non sono esperti di programmazione concorrente dovrebbero essere in grado di scrivere programmi corretti che possono essere facilmente rivisti e gestiti in progetti software più grandi. Se sei interessato a spremere fino all'ultimo livello di prestazioni, dovresti scrivere un'implementazione di coda specializzata che si adatta alle tue esigenze.

Problemi correlati