仓酷云
标题:
Linux设计Linux异步IO编程实例剖析仓酷云
[打印本页]
作者:
若天明
时间:
2015-1-18 11:26
标题:
Linux设计Linux异步IO编程实例剖析仓酷云
经常看到有人问用什么版本的linux好,其实只要你认真学习无论什么版本都挺好的。
在DirectIO形式下,异步长短常有需要的(由于绕过了pagecache,间接和磁盘交互)。linuxNativeAIO恰是基于这类场景计划的,详细的先容见:KernelAsynchronousI/O(AIO)SupportforLinux。上面我们就来剖析一下AIO编程的相干常识。
堵塞形式下的IO历程以下:
intfd=open(constchar*pathname,intflags,mode_tmode);
ssize_tpread(intfd,void*buf,size_tcount,off_toffset);
ssize_tpwrite(intfd,constvoid*buf,size_tcount,off_toffset);
intclose(intfd);
由于全部历程会守候read/write的前往,以是不必要任何分外的数据布局。但异步IO的头脑是:使用程序不克不及堵塞在高贵的体系挪用上让CPU睡年夜觉,而是将IO操纵笼统成一个个的义务单位提交给内核,内核完成IO义务后将了局放在使用程序能够取到的中央。如许在底层做I/O的这段工夫内,CPU能够往干其他的盘算义务。但异步的IO义务批量的提交和完成,必需有本身可形貌的布局,最主要的两个就是iocb和io_event。
libaio中的structs
structiocb{
void*data;/*Returnintheiocompletionevent*/
unsignedkey;/*ruseinidentifyingiorequests*/
shortaio_lio_opcode;
shortaio_reqprio;
intaio_fildes;
union{
structio_iocb_commonc;
structio_iocb_vectorv;
structio_iocb_pollpoll;
structio_iocb_sockaddrsaddr;
}u;
};
structio_iocb_common{
void*buf;
unsignedlongnbytes;
longlongoffset;
unsignedflags;
unsignedresfd;
};
iocb是提交IO义务时用到的,能够完全地形貌一个IO哀求:
data是留给用来自界说的指针:能够设置为IO完成后的callback函数;
aio_lio_opcode暗示操纵的范例:IO_CMD_PWRITE|IO_CMD_PREAD;
aio_fildes是要操纵的文件:fd;
io_iocb_common中的buf,nbytes,offset分离纪录的IO哀求的membuffer,巨细和偏移。
structio_event{
void*data;
structiocb*obj;
unsignedlongres;
unsignedlongres2;
};
io_event是用来形貌前往了局的:
obj就是之条件交IO义务时的iocb;
res和res2来暗示IO义务完成的形态。
libaio供应的API和完成IO的历程
libaio供应的API有:io_setup,io_submit,io_getevents,io_destroy。
1.创建IO义务
intio_setup(intmaxevents,io_context_t*ctxp);
io_context_t对应内核中一个布局,为异步IO哀求供应高低文情况。注重在setup前必需将io_context_t初始化为0。
固然,这里也必要open必要操纵的文件,注重设置O_DIRECT标记。
2.提交IO义务
longio_submit(aio_context_tctx_id,longnr,structiocb**iocbpp);
提交义务之前必需先添补iocb布局体,libaio供应的包装函数申明了必要完成的事情:
voidio_prep_pread(structiocb*iocb,intfd,void*buf,size_tcount,longlongoffset)
{
memset(iocb,0,sizeof(*iocb));
iocb->aio_fildes=fd;
iocb->aio_lio_opcode=IO_CMD_PREAD;
iocb->aio_reqprio=0;
iocb->u.c.buf=buf;
iocb->u.c.nbytes=count;
iocb->u.c.offset=offset;
}
voidio_prep_pwrite(structiocb*iocb,intfd,void*buf,size_tcount,longlongoffset)
{
memset(iocb,0,sizeof(*iocb));
iocb->aio_fildes=fd;
iocb->aio_lio_opcode=IO_CMD_PWRITE;
iocb->aio_reqprio=0;
iocb->u.c.buf=buf;
iocb->u.c.nbytes=count;
iocb->u.c.offset=offset;
}
这里注重读写的buf都必需是按扇区对齐的,能够用posix_memalign来分派。
3.猎取完成的IO
longio_getevents(aio_context_tctx_id,longmin_nr,longnr,structio_event*events,structtimespec*timeout);
这里最主要的就是供应一个io_event数组给内核来copy完成的IO哀求到这里,数组的巨细是io_setup时指定的maxevents。
timeout是指守候IO完成的超不时间,设置为NULL暗示一向守候一切到IO的完成。
4.烧毁IO义务
intio_destroy(io_context_tctx);
libaio和epoll的分离
在异步编程中,任何一个环节的堵塞城市招致全部程序的堵塞,以是必定要制止在io_getevents挪用时堵塞式的守候。还记得io_iocb_common中的flags和resfd吗?看看libaio是怎样供应io_getevents和事务轮回的分离:
voidio_set_eventfd(structiocb*iocb,inteventfd)
{
iocb->u.c.flags|=(1<<0)/*IOCB_FLAG_RESFD*/;
iocb->u.c.resfd=eventfd;
}
这里的resfd是经由过程体系挪用eventfd天生的。
inteventfd(unsignedintinitval,intflags);
eventfd是linux2.6.22内核以后加出去的syscall,感化是内核用来关照使用程序产生的事务的数目,从而使使用程序不必频仍地往轮询内核是不是偶然间产生,而是有内核将产生事务的数目写进到该fd,使用程序发明fd可读后,从fd读取该数值,并即刻往内核读取。
有了eventfd,就能够很好地将libaio和epoll事务轮回分离起来:
1.创立一个eventfd
efd=eventfd(0,EFD_NONBLOCK|EFD_CLOEXEC);
2.将eventfd设置到iocb中
io_set_eventfd(iocb,efd);
3.交代AIO哀求
io_submit(ctx,NUM_EVENTS,iocb);
4.创立一个epollfd,并将eventfd加到epoll中
epfd=epoll_create(1);
epoll_ctl(epfd,EPOLL_CTL_ADD,efd,&epevent);
epoll_wait(epfd,&epevent,1,-1);
5.当eventfd可读时,从eventfd读出完成IO哀求的数目,并挪用io_getevents猎取这些IO
read(efd,&finished_aio,sizeof(finished_aio);
r=io_getevents(ctx,1,NUM_EVENTS,events,&tms);
一个完全的编程实例
http://blog.sina.com.cn/s/blog_6b19f21d0100znza.html
以上就是linux异步IO编程的一些基本常识,但愿对感乐趣的同砚或多或少有些协助,感谢。
linux系统的文件布置,etc/,opt/目录的内容等;
作者:
灵魂腐蚀
时间:
2015-1-21 06:37
一定要养成在命令行下工作的习惯,要知道X-window只是运行在命令行模式下的一个应用程序。在命令行下学习虽然一开始进度较慢。
作者:
柔情似水
时间:
2015-1-25 22:43
对Linux命令熟悉后,你可以开始搭建一个小的Linux网络,这是最好的实践方法。Linux是网络的代名词,Linux网络服务功能非常强大,不论是邮件服务器、Web服务器、DNS服务器等都非常完善。
作者:
深爱那片海
时间:
2015-2-4 06:59
然我们对Linux的学习首先是通过对它的产生,发展,到今天仍然在不断完善开始的。
作者:
只想知道
时间:
2015-2-5 11:14
上课传授的不仅仅是知识,更重要的是一些道理,包括一些做人的道理,讲课时也抓住重点,循序渐进,让同学理解很快;更可贵的是不以你过去的成绩看问题.
作者:
简单生活
时间:
2015-2-5 21:24
在学习linux的工程中,linux学习方法有很多种,这里是小编的学习心得,给大家拿出来分享一下。
作者:
再见西城
时间:
2015-2-7 13:47
学习Linux应具备的。[书籍+网络资源]
作者:
飘飘悠悠
时间:
2015-2-11 16:51
在学习的过程中,我们用的是VM虚拟机,开始时真的不真的该怎么去做,特别是我的是命令窗口界面,别人的是图形界面,我都不知道怎么调过来。
作者:
小女巫
时间:
2015-2-28 21:55
其实当你安装了一个完整的Linux系统后其中已经包含了一个强大的帮助,只是可能你还没有发现和使用它们的技巧。
作者:
山那边是海
时间:
2015-3-10 08:10
Linux的成功就在于用最少的资源最短的时间实现了所有功能,这也是符合人类进化的,相信以后节能问题会日益突出。
作者:
海妖
时间:
2015-3-11 04:31
掌握硬件配置,如显卡,声卡,网卡等,硬件只要不是太老或太新一般都能被支持,作为一名Linux系统管理员建议多阅读有关硬件配置文章,对各种不支持或支持不太好的硬件有深刻的了解。
作者:
兰色精灵
时间:
2015-3-13 04:44
在系统检测不到与Linux兼容的显卡,那么此次安装就可能不支持图形化界面安装,而只能用文本模式安装等等。
作者:
admin
时间:
2015-3-20 13:08
未来的学习之路将是以指数增加的方式增长的。从网管员来说,命令行实际上就是规则,它总是有效的,同时也是灵活的。
欢迎光临 仓酷云 (http://ckuyun.com/)
Powered by Discuz! X3.2