网络IO之阻塞、非阻塞、同步、异步总结

http://blog.csdn.net/historyasamirror/article/details/5778378

http://www.cnblogs.com/Anker/p/3254269.html


对于一个network IO(以read为例),它会涉及到两个系统对象,一个是调用该IO的process(or thread),另一个是系统内核(kernel),当一个read操作发生时,它会经历两个阶段
1. 等待数据准备(Waiting for the data to be ready)
2. 将数据从内核拷贝到进程中(Copying the data from kernel to the process)


1. blocking IO
在linux中,默认情况下所有的socket都是blocking,
当用户进程调用了recvfrom这个系统调用,kernel就开始了IO的第一个阶段:准备数据。对于network IO来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的UDP包),这个时候kernel就要等待足够的数据到来,而在用户进程这边,整个进程会被阻塞。当kernel一直等到数据准备好了,它就会将数据从kernel中拷贝到用户内存,然后kernel返回结果,用户进程才解除block的状态,重新运行起来。
所以,blocking IO的特点就是在IO执行的两个阶段都被block了。


2. non-blocking IO
linux下,可以通过设置socket使其变为non-blocking
当用户进程发出read操作时,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error。从用户角度讲,它发起一个read操作后,并不需要等待,而是马上得到了一个结果。用户进程判断结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call,那么它就将数据拷贝到了用户内存,然后返回。
所以,用户进程其实是需要不断的主动询问kernel数据好了没有。


3. IO multiplexing (select, poll, epoll) event driven IO
基本原理是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达时,就通知用户进程。
当用户进程调用了select,整个进程就会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就返回,这个时候用户进程再调用read操作,将数据从kernel拷贝到用户进程。


4. Asynchronous IO
当用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它收到一个asynchronous read之后,首先会立刻返回,所以不会对用户进行产生任何block,然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值