自己总结的linux下面的异步IO操作

Song 2006-09-15 11:40:40
linux在2.6内核中实现了对网络的异步IO
我用的linux是Redhat AS4 , 64位的版本
下面是个利用异步IO对网络数据进行读取的例子

char buf[1024]; //定义一个接收缓冲区
int newfd = accept(m_Listen_handle, (struct sockaddr*)&addr, &len); //接收新连接,这里还是阻塞的
struct aiocb myaiocb; //定义一个类型于overlapped的结构
bzero( &myaiocb, sizeof (struct aiocb)); //这句不能少,否则会出现EINVAL
myaiocb.aio_fildes= newfd; //要读取的句柄
//myaiocb.aio_fildes= open( "main.cpp", O_RDONLY); //如果是要读磁盘文件可以这样
myaiocb.aio_offset= 0; //指定要开始读取的偏移量
myaiocb.aio_buf= (void*)buf; //把接收缓冲区指向刚才定义的缓冲区
myaiocb.aio_nbytes= sizeof(buf); //指定缓冲区大小
ssize_t rt=aio_read(&myaiocb); //----------异步读
if( rt==0 )
{
//调用成功,返回0
aiocb* aiocb_list[1]; //定义一个指针数组,用来存放IO的结果,因为这里只对一个句柄进行读取,所以只定义了一个
aiocb_list[0]= &myaiocb; //指向刚才的结构
size_t aiocb_list_max_size=1; //aio_suspend最大会返回多少个结果
while(1) //循环接收IO结果
{
rt= aio_suspend(aiocb_list, aiocb_list_max_size, NULL); //----------取出完成的IO,NULL表示永不操时退出
if( rt==-1)
{
//调用出错
if (errno != EAGAIN && errno != EINTR ) //不是被信号中断
{
/* wait for completion */
while ( (rt = aio_error( &myaiocb) ) == EINPROGRESS); //EINPROGRESS表示操作还未完成,要等待?
ssize_t nbytes = aio_return( &myaiocb);
cout<<"aio_error:"<<rt<<endl;
cout<<"aio_return:"<<nbytes<<endl;
cout<<"errno:"<<errno<<endl;
break;
}
else
{
//timeout or Interrupted call
cout<<"timeout or Interrupted call"<<endl;
continue;
}
}
else
{
size_t aiort= aio_return(aiocb_list[0]); //这个值表示实际读出了多少字节
if( aiort==0 )
{
//当读到0字节,网络断开了???
close(newfd);
break;
}
if( aiocb_list[0] !=NULL )
{
cout<<"recv , size: "<<aiort<<endl;
cout<<"recv , buf: "<<(char*)(aiocb_list[0]->aio_buf)<<endl;
bzero(buf, sizeof(buf));
ssize_t rt=aio_read(&myaiocb); //继续发起异步读
if( rt==0 )
continue;
}
break;
}
}
}
else
{
if (errno == EAGAIN || errno == ENOMEM) //Ok, it will be deferred AIO
{
//应该可以重新发起aio_read,我这里就不继续了
}
/* wait for completion */
while ( (rt = aio_error( &myaiocb) ) == EINPROGRESS) ;
ssize_t nbytes = aio_return( &myaiocb);
cout<<"aio_error:"<<rt<<endl;
cout<<"aio_return:"<<nbytes<<endl;
sout<<"errno:"<<errno<<endl;
}

这是我第一次写的,有错误在所难免,望请指出 - Song
...全文
574 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Song 2006-09-19
  • 打赏
  • 举报
回复
说Socket AIO 会自动变成同步操作,这一点我没有去研究。但肯定不是在aio_read或aio_suspend里面去调用阻塞的read来实现的。也许LINUX内部用线程去模拟异步IO,但表现出来的性质是异步IO,aio_read会马上返回,并在aio_suspend里等待IO的完成事件
Song 2006-09-19
  • 打赏
  • 举报
回复
http://lse.sourceforge.net/io/aio.html 我看过了, 我说肯定不是,是指aio_read不会阻塞,而aio_suspend也不可能直接调用read, 至于里面是不是利用线程+read来实现,我就不去研究了,至少使用上来说,它是异步方式的,而非同步的
Wolf0403 2006-09-19
  • 打赏
  • 举报
回复
yyyyssss:肯定不是?何以见得?我说会退化成同步 I/O 是抄自 aio linux 项目主页的说明,你不如写信去向他们证明你对他们代码的理解比他们更清楚。。
Wolf0403 2006-09-18
  • 打赏
  • 举报
回复
aio_read 支持 socket ??
Song 2006-09-18
  • 打赏
  • 举报
回复
epoll非异步IO,异步IO的优点可以参考WINDOWS完成端口
Wolf0403 2006-09-18
  • 打赏
  • 举报
回复
AIO read and write on sockets (doesn't return an explicit error, but quietly defaults to synchronous or rather non-AIO behavior)

根据http://lse.sourceforge.net/io/aio.html的说法,Socket AIO 会自动变成同步操作。简单看了一下代码也确实如此。
Wolf0403 2006-09-18
  • 打赏
  • 举报
回复
似乎是我错了。
Song 2006-09-15
  • 打赏
  • 举报
回复
hehe
healer_kx 2006-09-15
  • 打赏
  • 举报
回复
1分也是楼啊。
Arthur_ 2006-09-15
  • 打赏
  • 举报
回复
why not epoll

64,645

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧