通道 (编程)

在计算中，通道（channel）是通过消息传递进行进程间通信和同步的编程模型。作为一个流，消息可以经由通道发送，另一个进程或线程能够接收它已经引用的经由通道发送的消息。通道的不同实现，可以没有缓冲区也可以有缓冲区，消息传递相应的可以是同步的也可以是异步的。

通道是并发的进程演算方式的基础，并起源于通信顺序进程（CSP），它是并发的形式模型，在CSP的无缓冲区通道中，发送者不能传送消息，直到接收者准备好接受它，称为同步消息传递，这种行为也被形象的称为“约会”（rendezvous）。通道已经用在了很多CSP派生语言中，比如occam和Limbo编程语言（通过了Newsqueak和Alef语言）。通道还用于贝尔实验室Plan 9的libthread，以及用于Stackless Python和Go编程语言。

通道实现
通道是固有同步I/O：一个进程等待接收来自一个通道的对象，它将会阻塞直到这个对象被发送了。

libthread通道
多线程库libthread，它最初是为操作系统Plan 9建立的，提供了基于固定大小的通道的线程间通信。下面用libthread通道API的例子来说明典型支持的操作。
 固定或可变大小的通道建立，返回引用或句柄（handle）：Channel* chancreate(int elemsize, int bufsize)
 发送到一个通道：int chansend(Channel *c, void *v)
 接收自一个通道：int chanrecv(Channel *c, void *v)

OCaml事件
OCaml事件模块提供有类型的通道用于同步。在调用这个模块的发送和接收函数的时候，它们建立可以被同步的相应发送和接收事件。

例子

XMOS XC 

编程语言XC提供了原始类型chan，和两个算符<:和:>用于对通道的发送和接收数据。XC语言还允许通过select语句在通道上异步接收。

在下面的例子中，两个硬件线程在XMOS上启动，运行par块中那两行代码。第一行传输数42至通道，而第二行等待直到它接收到并设置为x的值。

chan c;
int x;
par {
  c <: 42;
  c :> x;
}

Go 

Go允许通道缓冲内容，而且还有通过使用select阻塞而得到的非阻塞接收。下面是演示通道和goroutine协程用法Go代码片段：

c := make(chan int)  // 分配一个通道
// 启动一个goroutine在其中做排序；当它完成时，在通道上发信号
go func() {
    list.Sort()
    c <- 1  // 发送一个信号，值无关紧要
}()
doSomethingForAWhile()
<-c   // 等待排序结束；丢弃发来的值

应用 
除了用于进程间通信的基本用途之外，通道可以被用作实现能现实化为流的各种其他并发编程构造的原语（primitive）。例如，可以使用通道了构造Future与promise，这里的future是一个一元素通道，而promise是发送至这个通道的一个进程，它满足future。类似的，迭代器可以直接用通道构造。

引用

参见
通信顺序进程
管道 (软件)

外部链接 
 Bell Labs and CSP Threads ，贝尔实验室及CSP线程模型。
 An Introduction to Programming with Threads , 与“贝尔实验室及CSP线程”相对比的SRC线程模型。

进程间通信
Go软件