您的位置:首页 > 理论基础 > 计算机网络

网络IO模型及同步、异步与阻塞、非阻塞的理解

2017-06-24 12:01 781 查看

1.Linux常见IO模型 .

常见IO分为下面两个流程 :

(1) 等待数据准备好

(2) 从内核向进程复制数据 .

对于一个套接字的输入操作, 第一步通常涉及等待数据从网络中到达, 当所有等待分组到达时, 他被复制到内核的某个缓冲区 . 第二步就是数据从内核缓冲区复制到应用程序缓冲区 .

阻塞IO模型 :

标红部分是阻塞, 直到阻塞结束recvfrom才能返回 .



非阻塞式IO :

recvfrom从应用层到内核的时候, 如果该缓冲区没有数据就直接返回EWOULDBLOCK错误, 一般对非阻塞IO模型进行轮训检查这个状态看是否有数据到来 .

可以看到recvfrom总是立即返回.



IO多路复用 :

虽然IO多路复用函数也是阻塞的, 但是其与以上两种不同, IO多路复用是阻塞在select, epoll这样系统调用上 . 而没有阻塞在真正的IO系统调用如recvfrom上. 也就是说将阻塞点改变了位置 .



异步IO :

红线部分调用立即返回, 等函数操作完成后通知我们 .



前三种IO模型都是同步IO模型, 区别是在第一阶段, 而他们第二阶段是一样的 : 在数据从内核复制到对应缓冲区期间(用户空间), 进程阻塞于recvfrom 调用 . 也就是说在复制数据到用户态的阶段它们都是阻塞的 .

所以上面的阻塞模型、非阻塞模型、多路IO复用,都是同步IO,异步必定是非阻塞的,所以不存在异步阻塞和异步非阻塞的说法。真正的异步IO需要CPU的深度参与。换句话说,只有用户线程在操作IO的时候根本不去考虑IO的执行全部都交给CPU去完成,而自己只等待一个完成信号的时候,才是真正的异步IO。所以,创建一个子线程去轮询、去死循环,或者使用select、poll、epool,都不是异步。

2.总结 .

阻塞, 非阻塞 : 线程要访问的数据未准备就绪, 线程是否立即返回 . 如果调用立即返回就是非阻塞,反之.

同步, 异步 : 访问数据方式, 同步需要主动读写数据, 在读写数据过程中还是会阻塞; 异步只需要IO操作完成的通知, 并不主动读写数据, 由操作系统内核完成数据读写 .

参考 : https://www.zhihu.com/question/19732473
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息