123-POSIX 异步IO(异步操作状态)

当你使用 aio_read 或 aio_write 等函数发起了异步读或写时,内核就自己去干活了,假设你目前还不知道异步通知的方法,你就只能不断的询问内核:“你读完没?”,正如同前面的那段程序:

// 不断的检查异步读的状态,如果返回 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
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值