Автоматное программирование
- 1 year ago
- 0
- 0
Канал — модель межпроцессного взаимодействия и синхронизации через передачу сообщений в программировании. Сообщения могут быть посланы через канал, и другой процесс или поток, имеющий ссылку на канал, может получать поток сообщений, отправленных по каналу как поток . Различные реализации каналов могут быть синхронными или асинхронными, использовать буферизацию сообщений или нет.
Каналы являются основополагающими для подхода исчисления процессов и появились в взаимодействующих последовательных процессах (CSP), формальной модели параллелизма. Каналы используются во многих производных языках программирования, таких как Occam , Limbo (через языки и ). Они также используются в потоковой библиотеке языка программирования Си в ОС Plan 9 , а также в Stackless Python и языке Go .
Каналы, созданные по аналогии с моделью CSP, являются синхронными : процесс, ожидающий получения объекта из канала, блокируется, пока объект не будет отправлен. Такие реализации называют «rendezvous». Типичные операции над такими каналами представлены на примере интерфейсов каналов библиотеки libthread:
Channel* chancreate(int elemsize, int bufsize)
int chansend(Channel *c, void *v)
int chanrecv(Channel *c, void *v)
Потоковая библиотека , изначально созданная для ОС Plan 9 , предлагает возможности межпоточного взаимодействия через каналы фиксированного размера.
Модуль event языка OCaml реализует типизированные каналы для синхронизации. Когда вызываются функции send и receive модуля, они создают соответствующие события, которые могут быть синхронизированы.
В XMOS язык XC предоставляет встроенный тип «chan» и два оператора «<:» и «:>» для отправки и приема данных из канала.
В примере производится запуск двух аппаратных потоков в XMOS, исполняющих две строки из блока «par». Первая строка передает число 42 через канал. Вторая строка ожидает приема значения из канала и записывает полученное значение в переменную x. Язык XC также поддерживает асинхронный прием из каналов с помощью оператора select.
chan c;
int x;
par {
c <: 42;
c :> x;
}
Этот фрагмент кода Go сначала создает канал c, затем порождает goroutine, которая посылает 42 через канал. Когда число отправлено в канал, переменная x получит значение 42. Go позволяет каналам буферизировать содержимое. Возможна неблокирующая операция получения из канала с помощью блока select.
c := make(chan int)
go func() {c <- 42}()
x := <- c
В дополнение к использованию для межпоточного взаимодействия, каналы могут использоваться как примитив для реализации иных конкурентных конструкций. Например, каналы позволяют реализовать futures and promises , где future является одноэлементным каналом, а promise — процесс, который отправляет в канал, исполняя future. Сходным образом можно реализовать iterators через каналы.