参考文章
好文:还是这个写的最清楚
IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)
这些可以稍作参考,但是还是以第一篇为主。
socket阻塞与非阻塞,同步与异步,select,pool,epool
怎样理解阻塞非阻塞与同步异步的区别?
引文
wiki上认为 asynchronous IO和non-blocking IO是一回事。
blocking IO
linux默认的socket是blocking IO。
进程调用recvfrom,然后就被block了,一直等待。直到kernal等到了数据,把数据准备好,并拷贝到用户内存里才解除block。
non-blocking IO
将socket设置为non-blocking IO,用户进程调用recvfrom,如果kernal的数据没准备好,会直接返回错误,用户进程需要反复询问kernal的数据是否准备好。准备好了的时候,调用recvfrom就不会返回错误,可以对数据进行拷贝。
IO multiplexing(IO多路复用)
select和epoll就属于这种。
单个process可以处理多个网络连接的IO。
select/epoll这个function会不断轮询所有负责的socket,当某个socket的数据到达了,就通知用户进程。
用户调用了select,进程会被block,select开始轮询所有负责的socket,当某个socket的数据到达了,就通知用户进程,用户进程再调用recvfrom读取数据。
在IO multiplexing中每个socket都被设置为non-blocking的,select来轮询这些socket。
asynchronous IO
用户进程发起read操作之后,马上可以做其他事情,等到kernal把数据准备好,并拷贝到用户内存之后,kernal会发一个singal给用户进程通知他读好了。
所以到底区别是怎样
blocking IO会把用户进程block掉,直到读完数据。
non-blocking IO不会阻塞用户进程,马上返回一个结果,是错误,还是可以读,都马上返回。
除了最后一种asynchronous IO,其他的全都是synchronous IO,因为他们都要调用recvfrom,然后被block,然后拷贝到用户内存。
只有asynchronous IO,发起read操作之后直接撒手不管了,等待kernal的信号,完全没有被block。
最后重点对比non-blocking IO和asynchronous IO
non-blocking IO虽然是直接返回结果,但是还是需要用户进程不断调用recvfrom,而且,真正可以拷贝数据的时候还是被block。
而asynchronous IO把操作完全交给了kernal,kernal拷贝好了数据再通知用户进程。用户进程啥也不用干。