姓名
channel - 双向进程间通信
摘要
通道是消息的双向传输,由一些字节数据和一定句柄组成。
说明
通道有两个端点。从逻辑上讲,每个端点都会维护一个有序要读取的消息队列。如果向端点写入数据,则消息会在其他端点的队列中加入队列。当端点的最后一个句柄关闭时,该端点队列中的未读消息会被销毁。由于销毁消息会关闭该消息包含的所有句柄,因此关闭通道端点可能会产生递归效果(例如,通道包含一条消息,该消息包含通道,而该通道包含消息,依此类推)。
关闭某个渠道的最后一个句柄不会影响之前写入该频道的消息的生命周期。这为渠道提供了“触发后不理”语义。
一条消息由一些数据和一些句柄组成。调用 zx_channel_write()
会将一条消息加入队列,调用 zx_channel_read()
会将一条消息移出队列(如果有消息已加入队列)。线程可以处于阻塞状态,直到消息通过 zx_object_wait_one()
或其他等待机制进入待处理状态。
或者,调用 zx_channel_call()
会在通道的一个方向将消息加入队列,等待相应响应,然后将响应消息移出队列。在调用模式下,通过消息的前 4 个字节(称为事务 ID)标识相应的响应。内核会为使用 zx_channel_call()
写入的消息提供不同的事务 ID(始终设置高位)。
通过通道发送消息的过程包含两个步骤。第一种方法是以原子方式将数据写入通道,并将消息中所有句柄的所有权移到此通道中。此操作始终使用句柄:在调用结束时,所有句柄要么全部位于通道中,要么全部被舍弃。第二项操作是通道读取,与此类似:如果操作成功,下一条消息中的所有句柄都会以原子方式移动到接收进程的句柄表中。失败后,除非指定了 ZX_CHANNEL_READ_MAY_DISCARD 选项,否则频道会保留所有权,否则系统会丢弃这些频道。
与许多其他内核对象类型不同,通道是不可复制的。因此,每个通道端点只能关联一个句柄,并且持有该句柄的进程被视为所有者。只有所有者可以读取或写入消息,或者将通道端点发送到其他进程。
当通道端点的所有权从一个进程转移到另一个进程时,即使写入正在进行中,消息也不会被重新排序或被截断。转移事件之前的消息属于旧所有者,转移之后的消息属于新所有者。在传输端点时,如果读取正在进行中,也是如此。
即使从 ZX_RIGHT_DUPLICATE 右侧剥离最后一个句柄,系统也不会为其他内核对象提供上述顺序保证。
系统调用
zx_channel_call()
- 同步发送消息和接收回复zx_channel_create()
- 创建新频道zx_channel_read()
- 接收来自频道的消息zx_channel_write()
- 向频道发送消息
zx_object_wait_one()
- 等待一个对象的信号