自己总结的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