Windows网络编程-异步I/O与完成端口

  本文转载自http://www.cnblogs.com/Anker/p/3254269.html,http://jzhihui.iteye.com/blog/1629788 原作者写的更加详细。

   线程同步与异步:实际上同步与异步是针对应用程序与内核的交互而言的。同步过程中进程触发IO操作并等待或者轮询的去查看IO操作是否完成。异步过程中进程触发IO操作以后,直接返回,做自己的事情,IO交给内核来处理,完成后内核通知进程IO完成。同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法。按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等)。同步与异步如下图所示:



  I/O阻塞与非阻塞:简单理解为需要做一件事能不能立即得到返回应答,如果不能立即获得返回,需要等待,那就阻塞了,否则就可以理解为非阻塞。详细区别如下图所示:



阻塞式I/O模型:应用进程调用I/O操作时阻塞,只有等待要操作的数据准备好,并复制到应用进程的缓冲区中才返回。

非阻塞式I/O模型:当应用进程要调用的I/O操作会导致该进程进入阻塞状态时,该I/O调用返回一个错误,一般情况下,应用进程需要利用轮询的方式来检测某个操作是否就绪。数据就绪后,实际的I/O操作会等待数据复制到应用进程的缓冲区中以后才返回。

I/O复用模型:阻塞发生在select/poll的系统调用上,而不是阻塞在实际的I/O系统调用上。select/poll发现有数据就绪后,通过实际的I/O操作将数据复制到应用进程的缓冲区中。

异步I/O模型:应用进程通知内核开始一个异步I/O操作,并让内核在整个操作(包含将数据从内核复制到应该进程的缓冲区)完成后通知应用进程。

由异步I/O的定义来看,操作系统必须提供一种方式,在应用进程发出I/O操作后,可以在后台(而不是当前应用进程)完成数据等待和数据复制的工作,并最终通知应用进程I/O操作已经完成。

在Linux下有两种称为AIO的的接口:一个是由glibc提供,是由多线程来模拟:数据等待和数据复制的工作,由glibc创建线程来完成。数据复制完成后,执行I/O操作的线程通过回调函数的方式通知应用线程(严格来讲,这种方式不能算真正的AIO,因为用来执行实际I/O操作的线程还是阻塞在I/O操作上,只不过从应用进程的角度来看是异步方式的)。另一种是由内核提供的Kernel AIO,可以做到真正的内核异步通知(这种方式对读写方式,写入大小及偏移都有严格的要求),并且不支持网络I/O[1][2],其实现原理本质上与下面要介绍的IOCP类似。

还有一种称为IOCP(Input/Output Completion Port)的AIO。从实现原理上讲,IOCP做完I/O操作后,将结果封装成完成包(completion packet)入队到完成端口的队列(FIFO)中去,应用线程从队列中读取到完成消息后,处理后续逻辑。从这方面来讲,IOCP类似生产者-消费者模型:生产者为内核,收到应用线程的I/O请求后,等待数据可用,并将结果数据复制到应用线程指定的缓冲区中后,然后入队一个完成消息;消费者为应用线程,一开始向内核提交I/O请求,并在队列上等待内核的完成消息(只不过,IOCP对同时可运行的消费者有限制),收到完成消息后,进行后续处理。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值