123-POSIX 异步IO(异步操作状态)
2017-03-29 09:42
113 查看
当你使用 aio_read 或 aio_write 等函数发起了异步读或写时,内核就自己去干活了,假设你目前还不知道异步通知的方法,你就只能不断的询问内核:“你读完没?”,正如同前面的那段程序:
返回值有以下几种情况:
EINPROGRESS,异步请求未完成。
ECANCELED,异步请求被取消。
0,请求成功完成。
> 0 的错误码,表明异步操作失败,该值相当于同步 IO 函数 read、write 出错时,设置的 errno 变量。
aio_error 是线程安全的。
关于 aio_error 的实验,在前面的程序中已经演示过啦,就不重复了。这里还有一个新的函数叫 aio_return,也是获取异步操作的状态……
该函数返回最终的异步请求状态。
注意:这个函数对于每个请求只能使用一次,而且要在 aio_error 返回值不是 EINPROGRESS 的情况下使用。
重点看看返回值:
如果异步操作完成了,该函数返回值就相当于同步IO类函数 read, write, fsync 或 fdatasync 等的返回值。
如果异步操作未完成的情况下你使用了它,结果是未定义的!
代码
编译和运行
程序启动后,在终端输入了字符串
// 不断的检查异步读的状态,如果返回 EINPROGRESS,说明异步读还没完成 // 轮询检查状态是一种很笨的方式,其实可以让操作系统用信号的方式来通知,或者让操作系统完成读后主动创建一个线程执行。在后面我们会继续学习这两种通知方式。 while(aio_error(&my_aiocb) == EINPROGRESS) { write(STDOUT_FILENO, ".", 1); sleep(1); }
1. aio_error
error 这个名字很容易让人产生误解,实际上,它只是为了获取异步请求的状态。比如有没有读完?aio_error 的函数原型如下:int aio_error(const struct aiocb *aiocb);
返回值有以下几种情况:
EINPROGRESS,异步请求未完成。
ECANCELED,异步请求被取消。
0,请求成功完成。
> 0 的错误码,表明异步操作失败,该值相当于同步 IO 函数 read、write 出错时,设置的 errno 变量。
aio_error 是线程安全的。
关于 aio_error 的实验,在前面的程序中已经演示过啦,就不重复了。这里还有一个新的函数叫 aio_return,也是获取异步操作的状态……
2. aio_return
函数原型如下:// ssize_t 你就理解成 int 类型吧 ssize_t aio_return(struct aiocb *aiocbp);
该函数返回最终的异步请求状态。
注意:这个函数对于每个请求只能使用一次,而且要在 aio_error 返回值不是 EINPROGRESS 的情况下使用。
重点看看返回值:
如果异步操作完成了,该函数返回值就相当于同步IO类函数 read, write, fsync 或 fdatasync 等的返回值。
如果异步操作未完成的情况下你使用了它,结果是未定义的!
3. 实验
程序 my_aio_return.c 实际上只是将前面的代码稍稍做了修改。代码
// my_aio_return.c #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <aio.h> #include <strings.h> #include <errno.h> #define ERR_EXIT(msg) do { perror(msg); exit(1); } while(0) int main() { int fd, ret; char buf[64] = { 0 }; struct aiocb my_aiocb; bzero((char*)&my_aiocb, sizeof(struct aiocb)); my_aiocb.aio_buf = buf; my_aiocb.aio_fildes = STDIN_FILENO; my_aiocb.aio_nbytes = 64; my_aiocb.aio_offset = 0; ret = aio_read(&my_aiocb); if (ret < 0) ERR_EXIT("aio_read"); while(aio_error(&my_aiocb) == EINPROGRESS) { sleep(1); } // 获取最终的异步操作状态 ret = aio_return(&my_aiocb); if (ret < 0) ERR_EXIT("aio_return"); // 打印内容和返回值。 printf("content: %s, return: %d\n", buf, ret); return 0; }
编译和运行
$ gcc my_aio_return.c -o my_aio_return -lrt $ ./my_aio_return
程序启动后,在终端输入了字符串
hello后回车。然后在程序的界面打印出 hello 的内容,注意后面换行符也被送到缓冲区了,aio_return 返回的是读到的字节数。
4. 总结
掌握 aio_error 和 aio_return相关文章推荐
- swing登陆程序的异步loading效果,避免程序假死状态?swing 后台操作事件长 , 界面如何显示正在等待?
- 使用 Redux 管理状态,第 3 部分: 使用 Redux 实现异步操作
- 异步调用WebService抛出ArgumentException"异步处理过程中出现错误。未完成的多个异步并发操作需要唯一的状态对象"
- 124-POSIX 异步IO(等待异步IO操作)
- python实现自己的异步IO等异步操作
- 异步模块或处理程序已完成,而当时仍有异步操作处于未定状态
- Promise对象(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败
- 127-POSIX 异步IO(异步通知)
- WPF:在异步操作中使用CommandManager手动更新Command执行状态(转载)
- 125-POSIX 异步IO(取消操作)
- 利用线程进行异步操作
- 异步IO、APC、IO完成端口、线程池与高性能服务器之一 异步IO
- Remoting之异步操作模式
- .NET中的异步操作
- .Net中异步操作超时的设置方法
- MFC串口操作(异步方式)源码
- “多步操作产生错误,请检查每一步的状态”的解决方案
- .Net中异步操作超时的设置方法.
- 数据库异步操作(ADODB).
- 演示DataSet类不同状态的操作