多线程编程指南

异步 I/O

在多数情况下,不需要异步 I/O,因为其效果可借助线程得以实现,每个线程执行同步 I/O。但是,在少数情况下,线程不能实现异步 I/O 可以实现的效果。

最直观的示例就是写入磁带机以形成磁带机流。流形式可防止在向磁带机写入内容的同时磁带机停止运行。磁带将高速向前移动,同时提供写入磁带的连续不断的数据流。

要支持流形式,内核中的磁带机应使用线程。内核中的磁带机对中断做出响应时,该磁带机一定会发出排队的写入请求。中断指示以前的磁带写入操作已完成。

线程不能保证会对异步写入进行排序,因为线程执行的顺序是不确定的。例如,您无法指定写入磁带的顺序。

异步 I/O 操作

#include <sys/asynch.h>



int aioread(int fildes, char *bufp, int bufs, off_t offset,

    int whence, aio_result_t *resultp);



int aiowrite(int filedes, const char *bufp, int bufs,

    off_t offset, int whence, aio_result_t *resultp);



aio_result_t *aiowait(const struct timeval *timeout);



int aiocancel(aio_result_t *resultp);

aioread(3AIO)aiowrite(3AIO) 在格式上类似于 pread(2)pwrite(2),但是添加了最后一个参数。对 aioread()aiowrite() 的调用导致启动 I/O 操作或将该操作排入队列。

调用将顺利返回,而不被阻塞,而且调用的状态将在 resultp 所指向的结构中返回。resultpaio_result_t 类型的项,其中包含以下值:

int aio_return;

int aio_errno;

当调用立即失败时,可以在 aio_errno 中找到失败代码。否则,此字段将包含 AIO_INPROGRESS,意味着已成功地将操作排入队列。

等待 I/O 操作完成

通过调用 aiowait(3AIO),可以等待未完成的异步 I/O 操作完成。aiowait() 将返回指向 aio_result_t 结构(随原始 aioread(3AIO) 或原始 aiowrite(3) 调用一同提供)的指针。

此时,aio_result_t 将包含 read(2)write(2) ?òa?|^ao?H?§,前提是要调用其中一个函数而不是异步版本。如果 read()write() 成功,则 aio_return 包含已读取或写入的字节数。如果 read()write() 不成功,则 aio_return 为 -1,且 aio_errno 包含错误代码。

aiowait() 将使用 timeout 参数,该参数指示调用程序将等待的时间。此处的 NULL 指针表示调用程序将无限期等下去。指向包含零值的结构的指针表示调用程序根本不会等待。

您可能会启动异步 I/O 操作,执行某项工作,然后调用 aiowait() 以等待请求完成。或者,可以使用 SIGIO 在操作完成时以异步方式得到通知。

最后,可通过调用 aiocancel() 来取消暂挂的异步 I/O 操作。此例程是使用结果区域地址作为参数来进行调用的。此结果区域标识哪项操作将被取消。