网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 
中国网管联盟
Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道
 当前位置: > bitsCN.com > linux > 系统管理 > 内核技术 > 使用异步 I/O 大大提高应用程序的性能  

使用异步 I/O 大大提高应用程序的性能

2006-10-12  作者:网管整理  来源:bitsCN.com  点评 投稿 收藏

aio_return

网管网www_bitscn_com

    异步 I/O 和标准块 I/O 之间的另外一个区别是我们不能立即访问这个函数的返回状态,因为我们并没有阻塞在 read 调用上。在标准的 read 调用中,返回状态是在该函数返回时提供的。但是在异步 I/O 中,我们要使用 aio_return 函数。这个函数的原型如下: 网管u家u.bitscn@com


网管联盟bitsCN@com

ssize_t aio_return( struct aiocb *aiocbp );
       网管朋友网www_bitscn_net 

中国网管联盟bitsCN.com

    只有在 aio_error 调用确定请求已经完成(可能成功,也可能发生了错误)之后,才会调用这个函数。aio_return 的返回值就等价于同步情况中 readwrite 系统调用的返回值(所传输的字节数,如果发生错误,返回值就为 -1)。

网管联盟bitsCN@com

aio_write

网管联盟bitsCN_com

aio_write 函数用来请求一个异步写操作。其函数原型如下:

网管朋友网www_bitscn_net

int aio_write( struct aiocb *aiocbp );
       
网管有家www.bitscn.net

网管bitscn_com

  aio_write 函数会立即返回,说明请求已经进行排队(成功时返回值为 0,失败时返回值为 -1,并相应地设置 errno)。 网管u家u.bitscn@com

    这与 read 系统调用类似,但是有一点不一样的行为需要注意。回想一下对于 read 调用来说,要使用的偏移量是非常重要的。然而,对于 write 来说,这个偏移量只有在没有设置 O_APPEND 选项的文件上下文中才会非常重要。如果设置了 O_APPEND,那么这个偏移量就会被忽略,数据都会被附加到文件的末尾。否则,aio_offset 域就确定了数据在要写入的文件中的偏移量。 网管u家bitscn.net

aio_suspend

网管有家www.bitscn.net

     我们可以使用 aio_suspend 函数来挂起(或阻塞)调用进程,直到异步请求完成为止,此时会产生一个信号,或者发生其他超时操作。调用者提供了一个 aiocb 引用列表,其中任何一个完成都会导致 aio_suspend 返回。 aio_suspend 的函数原型如下: 网管联盟bitsCN_com

int aio_suspend( const struct aiocb *const cblist[],
                  int n, const struct timespec *timeout );
       网管有家bitscn.net 

网管网www.bitscn.com

   aio_suspend 的使用非常简单。我们要提供一个 aiocb 引用列表。如果任何一个完成了,这个调用就会返回 0。否则就会返回 -1,说明发生了错误。请参看清单 3。

网管联盟bitsCN_com


清单 3. 使用 aio_suspend 函数阻塞异步 I/O

  
struct aioct *cblist[MAX_LIST]
/* Clear the list. */
bzero( (char *)cblist, sizeof(cblist) );
/* Load one or more references into the list */
cblist[0] = &my_aiocb;
ret = aio_read( &my_aiocb );
ret = aio_suspend( cblist, MAX_LIST, NULL );
       

网管联盟bitsCN@com


网管有家www.bitscn.net

    注意,aio_suspend 的第二个参数是 cblist 中元素的个数,而不是 aiocb 引用的个数。cblist 中任何 NULL 元素都会被 aio_suspend 忽略。

网管bitscn_com

    如果为 aio_suspend 提供了超时,而超时情况的确发生了,那么它就会返回 -1errno 中会包含 EAGAIN网管u家bitscn.net

aio_cancel

网管u家bitscn.net

aio_cancel 函数允许我们取消对某个文件描述符执行的一个或所有 I/O 请求。其原型如下:

网管有家www.bitscn.net

int aio_cancel( int fd, struct aiocb *aiocbp );
       
网管bitscn_com

网管bitscn_com

     要取消一个请求,我们需要提供文件描述符和 aiocb 引用。如果这个请求被成功取消了,那么这个函数就会返回 AIO_CANCELED。如果请求完成了,这个函数就会返回 AIO_NOTCANCELED

网管有家www.bitscn.net

    要取消对某个给定文件描述符的所有请求,我们需要提供这个文件的描述符,以及一个对 aiocbpNULL 引用。如果所有的请求都取消了,这个函数就会返回 AIO_CANCELED;如果至少有一个请求没有被取消,那么这个函数就会返回 AIO_NOT_CANCELED;如果没有一个请求可以被取消,那么这个函数就会返回 AIO_ALLDONE。我们然后可以使用 aio_error 来验证每个 AIO 请求。如果这个请求已经被取消了,那么 aio_error 就会返回 -1,并且 errno 会被设置为 ECANCELED

网管下载dl.bitscn.com

lio_listio 网管网www.bitscn.com

    最后,AIO 提供了一种方法使用 lio_listio API 函数同时发起多个传输。这个函数非常重要,因为这意味着我们可以在一个系统调用(一次内核上下文切换)中启动大量的 I/O 操作。从性能的角度来看,这非常重要,因此值得我们花点时间探索一下。lio_listio API 函数的原型如下:

网管联盟bitsCN@com

int lio_listio( int mode, struct aiocb *list[], int nent,
                   struct sigevent *sig );
       

网管下载dl.bitscn.com


网管u家u.bitscn@com

   mode 参数可以是 LIO_WAITLIO_NOWAITLIO_WAIT 会阻塞这个调用,直到所有的 I/O 都完成为止。在操作进行排队之后,LIO_NOWAIT 就会返回。list 是一个 aiocb 引用的列表,最大元素的个数是由 nent 定义的。注意 list 的元素可以为 NULLlio_listio 会将其忽略。sigevent 引用定义了在所有 I/O 操作都完成时产生信号的方法。 网管联盟bitsCN@com

    对于 lio_listio 的请求与传统的 readwrite 请求在必须指定的操作方面稍有不同,如清单 4 所示。

网管有家bitscn.net


清单 4. 使用 lio_listio 函数发起一系列请求

  
struct aiocb aiocb1, aiocb2;
struct aiocb *list[MAX_LIST];
...
/* Prepare the first aiocb */
aiocb1.aio_fildes = fd;
aiocb1.aio_buf = malloc( BUFSIZE+1 );
aiocb1.aio_nbytes = BUFSIZE;
aiocb1.aio_offset = next_offset;
aiocb1.aio_lio_opcode = LIO_READ;
...
bzero( (char *)list, sizeof(list) );
list[0] = &aiocb1;
list[1] = &aiocb2;
ret = lio_listio( LIO_WAIT, list, MAX_LIST, NULL );
       网管u家www.bitscn.net 

网管下载dl.bitscn.com

    对于读操作来说,aio_lio_opcode 域的值为 LIO_READ。对于写操作来说,我们要使用 LIO_WRITE,不过 LIO_NOP 对于不执行操作来说也是有效的。

网管网www_bitscn_com

TAGs   应用程序   性能   提高   大大   使用   I/O   操作   请求   我们   aiocb      
 上一篇:内核研究 :CLFS2.0原理分析   下一篇:基于S3C2410处理器目标板的Linux移植
使用异步 I/O 大大提高应用程序的性能 评论:
loading.. 评论加载中…
评论:请自觉遵守互联网相关政策法规,评论不得超过250字。

验证码: 注册用户
本类热门排行:
最新推荐文章:
网管论坛交流: