3-POSIX异步IO(等待异步操作)

不知道你是否还记得线程中的 pthread_join 函数,它可以等待指定的线程完成结束后才会返回。同样的,在异步 IO 中,也有一个函数,但是它不是 aio_join,而是 aio_suspend,它会一直等待,直到指定的异步 IO 操作完成才返回。

1. aio_suspend

int aio_suspend(const struct aiocb * const aiocb_list[], int nitems, const struct timespec *timeout);

(1) 参数

这个函数参数看起来有点复杂,不过仔细看,实际上就是一个 aiocb 结构的指针数组。

  • aiocb_list:就是一个数组,这个数组存储的元素的类型是 const struct aiocb* 类型。如果某个元素为 NULL,aio_suspend 会忽略它。
  • nitems:aiocb_list 数组的大小。
  • timeout:超时时间,这个参数前面已经遇到过 N 次了。设置成 NULL 表示永远等待,直到异步 IO 操作完成。

(2) 函数语义

aio_suspend 函数会阻塞调用线程,直到发生下面的事情:

  • aiocb_list 中的一个或多个请求已完成。
  • 收到信号,被信号打断。
  • timeout 不空,指定的超时时间已过。

接下来看例子吧^_^

2. 实验

      同样是对前面程序的修改。

#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];
  // 定义一个异步控制块结构体,不懂没关系,不用管
  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; // 告诉内核,缓冲区大小只有 64
  my_aiocb.aio_offset = 0; // 告诉内核,从偏移为 0 的地方开始读

  // 发起异步读操作,立即返回。你并不知道何时 buf 中会有数据
  ret = aio_read(&my_aiocb);
  if (ret < 0) ERR_EXIT("aio_read");

  //为了传递aio_suspend用,创建一个大小为5的数组
  const struct aiocb *aio_list[5]={NULL};
  
  //将其中一元素赋值,不一定是第一个
  aio_list[4]=&my_aiocb;
  ret=aio_suspend(aio_list,5,NULL);
  if(ret<0)
  {
	  ERR_EXIT("aio_suspend"); 
  }
  printf("aio_suspend return\n");
  // 不断的检查异步读的状态,如果返回 EINPROGRESS,说明异步读还没完成
  // 轮询检查状态是一种很笨的方式,其实可以让操作系统用信号的方式来通知,或者让操作系统完成读后主 动创建一个线程执行。
  while(aio_error(&my_aiocb) == EINPROGRESS) {
       puts("EINPROGRESS");
  }
  ret=aio_return(&my_aiocb);
  if(ret<0)
  {
	  ERR_EXIT("aio_return");
  }
  // 打印缓冲区内容,你并不知道内核是什么时候将缓冲区中的 hello 复制到你的 buf 中的。
  printf("content: %s,return:%d\n", buf,ret);

  return 0;
  
}

编译与运行

       

                                                                              图1运行结果

      启动程序后,程序首先会在 aio_suspend 处阻塞,在终端输入hello world 后,aio_suspend 就返回了。

3. 总结

  • 掌握 aio_suspend 函数的语义和用法

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

4-POSIX 异步IO(批量请求)

转自:https://blog.csdn.net/q1007729991/article/details/68060889

猜你喜欢

转载自blog.csdn.net/m0_37806112/article/details/82312692
今日推荐