程序设计之异步操作

原文: http://blog.sina.com.cn/s/blog_4d6f62190100gtxw.html

 

异步操作,就我个人理解而言,是指一个单一事务的操作过程中,不会因为由于事务中的单个慢操作而堵塞事务的关键路径,从而影响处理的整体性能。从一个老外 的一篇文章中,看到了他对阻塞以及异步的整体理解,从这个理解出发,阻塞和异步互不冲突,同步的操作可以是阻塞的也可以是非阻塞的,异步的操作也可以是阻 塞或者是非阻塞的。

同步以及阻塞与否,对象涉及到了调用者进程以及被调用数据读取函数。

                 阻塞              非阻塞   

           -------------------------------------  

      同步 | read/write      |  read/write     |

           | (block)       |  (no block)     |

           -------------------------------------

      异步 |   IO多路复用    |     AIO         |

           |                 |                 |

           ------------------------------------- 

同步的阻塞操作:同步操作指的调用进程调用数据读取函数后,不能立即返回,必须等待对应数据读取函数获得数据后才能继续往下执行;阻塞的意思是指数据读取 函数如果不能立即获得数据而阻塞在该调用上。

同步的非阻塞操作:这种情况下,如果数据读取函数不能立即获得数据,将会立即返回,不会由于该函数的调用而阻塞对应的进程,后续调用进程必须主动再次调用 对应数据读取函数,再次尝试获取数据。

 

异步阻塞操作:这里的阻塞实际上是针对调用进程来说的,虽然IO多路复用可以实现事件的通知,但是调用进程仍旧需要主动查询对应的多路复用之内的事件,如 果没有事件发生,则会阻塞在该查询操作上。

 

高级的异步非阻塞操作来了,那就是大名鼎鼎的aio,aio是linux2.6以上内核中的一个属于realtime lib的调用接口组,所有对数据读取函数的调用都不会阻塞对应的调用上,同时也不需要调用进程主动地查询数据读写的状况,而是采用进程内的信号通知机制或 者预先注册的线程回调函数将数据ready事件通知给调用主进程。

 

可惜的是

Linux Kernel 2.6提供了对AIO的有限支持——仅支持文件系统,而表面上的异步IO也仅仅是libc的模拟而已,性 能上也没有什么优势。

代码示例如下:

#include <aio.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

struct aiocb * cb[2];

//The signal number to use.
#define SIG_AIO SIGRTMIN+5

//Signal handler called when an AIO operation finishes
void aio_handler(int signal, siginfo_t *info, void*uap)
{
 int cbNumber = info->si_value.sival_int;
 printf("AIO operation %d completed returning %d/n",
  cbNumber,
  aio_return(cb[cbNumber]));
}

int main(void)
{
 struct sigaction action;
 //Create a buffer to store the read data
 char * foo = calloc(1,20);
 //Set up the signal handler
 action.sa_sigaction = aio_handler;
 action.sa_flags = SA_SIGINFO;
 sigemptyset(&action.sa_mask);
 sigaction(SIG_AIO, &action, NULL);
 FILE * file = fopen("bar", "r+");
 
 //Allocate space for the aio control blocks
 cb[0] = calloc(1,sizeof(struct aiocb));
 cb[1] = calloc(1,sizeof(struct aiocb));
 //Somewhere to store the result
 cb[0]->aio_buf = foo;
 cb[1]->aio_buf = foo + 10;
 //The file to read from
 cb[0]->aio_fildes = fileno(file);
 cb[1]->aio_fildes = fileno(file);
 //The number of bytes to read, and the offset
 cb[0]->aio_nbytes = 10;
 cb[1]->aio_nbytes = 10;
 cb[0]->aio_offset = 0;
 cb[1]->aio_offset = 10;
 //The signal to send, and the value of the signal
 cb[0]->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
 cb[0]->aio_sigevent.sigev_signo = SIG_AIO;
 cb[0]->aio_sigevent.sigev_value.sival_int = 0;
 cb[1]->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
 cb[1]->aio_sigevent.sigev_signo = SIG_AIO;
 cb[1]->aio_sigevent.sigev_value.sival_int = 1;

 aio_read(cb[0]);
 aio_read(cb[1]);
 while(1){sleep(1);}
 sleep(1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值