Kanál je model pro meziprocesovou komunikaci a synchronizaci prostřednictvím předávání zpráv v programování. Zprávy lze odesílat přes kanál a jiný proces nebo vlákno, které má odkaz na kanál, může přijímat proud zpráv odeslaných přes kanál jako stream . Různé implementace kanálů mohou být synchronní nebo asynchronní, používat ukládání zpráv do vyrovnávací paměti nebo ne.
Kanály jsou základem přístupu procesního kalkulu a vznikly v Cooperating Sequential Processes (CSP), formálním modelu souběžnosti. Kanály se používají v mnoha odvozených programovacích jazycích, jako je Occam , Limbo (prostřednictvím jazyků Newsqueak a Aleph ). Používají se také v knihovně vláken libthread programovacího jazyka C v OS Plan 9 , stejně jako v Stackless Pythonu a jazyce Go .
Kanály, vytvořené podobně jako model CSP, jsou synchronní : proces čekající na přijetí objektu z kanálu blokuje, dokud není objekt odeslán. Takové implementace se nazývají "rendezvous". Typické operace na takových kanálech jsou prezentovány pomocí rozhraní kanálu libthread jako příklad:
Knihovna vláken libthread , původně vytvořená pro OS Plan 9 , nabízí možnosti komunikace mezi vlákny prostřednictvím kanálů s pevnou velikostí.
Modul událostí OCaml implementuje typované kanály pro synchronizaci. Když jsou volány funkce odesílání a přijímání modulu, generují odpovídající události, které lze synchronizovat.
V XMOS poskytuje jazyk XC vestavěný typ „chan“ a dva operátory „<:“ a „:>“ pro odesílání a přijímání dat z kanálu. [jeden]
Příklad spustí dvě hardwarová vlákna v XMOS, provádějící dva řádky z bloku "par". První řádek posílá číslo 42 potrubím. Druhý řádek čeká na přijetí hodnoty z kanálu a zapíše přijatou hodnotu do proměnné x. Jazyk XC také podporuje asynchronní příjem z kanálů pomocí příkazu select.
chan c ; int x ; par { c <: 42 ; c :> x ; }Tento kus kódu Go nejprve vytvoří kanál c, poté vytvoří goroutinu, která pošle 42 kanálem. Když je do kanálu odesláno číslo, x bude nastaveno na 42. Go umožňuje kanálům ukládat obsah do vyrovnávací paměti. Operace příjmu bez blokování z kanálu je možná pomocí bloku výběru. [2]
c := make ( chan int ) go func () { c <- 42 } () x := <- cKromě použití pro komunikaci mezi vlákny lze kanály použít jako primitiva k implementaci dalších souběžných konstrukcí. Kanály vám například umožňují implementovat futures a sliby , kde budoucnost je samostatný kanál a slib je proces, který posílá do kanálu a provádí budoucnost. [3] Podobně lze iterátory implementovat pomocí potrubí. [čtyři]