В вычислениях канал — это модель межпроцессного взаимодействия и синхронизации посредством передачи сообщений . Сообщение может быть отправлено по каналу, а другой процесс или поток может получать сообщения, отправленные по каналу, на который он имеет ссылку , в виде потока . Различные реализации каналов могут быть с буферизацией или без нее, а также быть синхронными или асинхронными.
Многопоточная библиотека libthread, впервые созданная для операционной системы Plan 9 , предлагает межпоточную связь на основе каналов фиксированного размера.
Модуль событий OCaml предлагает типизированные каналы для синхронизации. Когда вызываются функции отправки и получения модуля, они создают соответствующие события отправки и получения, которые можно синхронизировать.
Библиотека Love2D , которая является частью языка программирования Lua , реализует каналы с операциями push и pop, похожими на стеки. Операция извлечения будет заблокирована до тех пор, пока в стеке находятся данные. Операция запроса эквивалентна операции pop, за исключением того, что она блокируется до тех пор, пока в стеке не появятся данные.
-- Строка, содержащая код, который будет интерпретироваться такой функцией, как loadstring(), -- но на стороне C для запуска собственного потока.local threadCode = [[ love.thread.getChannel("test"):push("Привет, мир!") ]]функция любовь . load () -- Запускаем поток. нить = любовь . нить . newThread ( threadCode ) поток : начало () -- Поток будет заблокирован до тех пор, пока не появится сообщение "Hello world!" извлекается из стека теста канала. -- Поскольку канал может быть извлечен до первого выполнения потока, в стеке может не оказаться данных. -- в этом случае используйте :demand() вместо :pop(), потому что :demand() будет блокироваться до тех пор, пока в стеке не появятся данные, а затем вернет данные. печать ( любовь . нить . getChannel ( «тест» ): спрос ()) -- Теперь поток может завершиться. конец
Язык программирования XMOS XC предоставляет примитивный тип «chan» и два оператора «<:» и «:>» для отправки и получения данных из канала. [1]
В этом примере на XMOS запускаются два аппаратных потока, выполняющие две строки в блоке «par». Первая строка передает по каналу число 42, а вторая ждет его получения и устанавливает значение x. Язык XC также позволяет асинхронный прием по каналам с помощью оператора выбора.
чан с ; интервал х ; пар { с <: 42 ; с :> х ; }
Этот фрагмент кода Go работает аналогично коду XC. Сначала создается канал c, затем запускается горутина, которая отправляет 42 через канал. Когда число помещается в канал, x устанавливается равным 42. Go позволяет каналам буферизировать содержимое, а также неблокировать прием за счет использования блока выбора. [2]
c := make ( chan int ) go func () { c <- 42 }() х := <- с
Rust предоставляет асинхронные каналы для связи между потоками. Каналы обеспечивают однонаправленный поток информации между двумя конечными точками: Sender
и Receiver
. [3]
используйте std :: sync :: mpsc ; используйте std :: thread ; fn main () { let ( tx , rx ) = mpsc :: channel (); поток :: spawn ( move || { tx . send ( 123 ). unwrap (); }); пусть результат = rx . получение (); распечататьлн! ( "{:?}" , результат ); }
В дополнение к их фундаментальному использованию для межпроцессного взаимодействия, каналы могут использоваться в качестве примитива для реализации различных других конструкций параллельного программирования, которые могут быть реализованы в виде потоков. Например, каналы можно использовать для построения фьючерсов и промисов , где фьючерс — это одноэлементный канал, а промис — это процесс, который отправляет данные в канал, исполняя будущее. [4] Аналогично, итераторы могут быть созданы непосредственно из каналов. [5]