在 BSD 及其派生系统中,异步 I/O 是信号 SIGIOSIGURG 的组合,其中 SIGIO 是通用异步 I/O 信号,SIGURG 则仅用来通知进程在网络连接上到达了带外的数据。

接收 SIGIO 信号需要执行三个步骤:

  1. 调用 signalsigactionSIGIO 信号简历信号处理程序

  2. F_SETOWN 调用 fcntl 来设置进程 ID 和进程组 ID,它们将接收对于该描述符的信号

  3. F_SETEL 调用 fcntl 来设置 O_ASYNC 文件状态标志,使在该描述符上可以进行异步 I/O,附表:

fcntl 文件状态标志描述
O_RDONLY只读打开
O_WRONLY只写打开
O_RDWR可读可写打开
O_APPEND每次写时追加
O_NONBLOCK非阻塞模式
O_SYNC等待写完成(数据与属性)
O_DSYNC等待写完成(数据)
O_RSYNC同步读写
O_FSYNC等待写完成(FreeBSD/Mac OS X)
O_ASYNC异步 I/O(FreeBSD/Mac OS X)

O_RDONLYO_WRONLYO_RDWR 并非各占 1 位,由于历史原因,他们的值分别是 0、1、2,一个文件只能使用他们之中的一个,因此需要用屏蔽字 O_ACCMODE 取得访问模式位,然后将结果与这三者之一做比较。

其中,步骤 3. 只能对指向终端或网络的描述符执行,这是 BSD 异步 I/O 设施的一个基本限制。

对于 SIGURG 信号,只需要执行步骤 1.2.,该信号只对引用支持带外数据的网络连接描述符产生。