阻塞&非阻塞

阻塞IO

调用之后一定要等到系统内核完成所有的操作之后才结束,因此它的缺点:CPU等待IO,处理能力得不到充分利用。

非阻塞IO

为了解决阻塞IO带来的一些问题,内核提供了非阻塞IO,非阻塞IO的差别是调用之后会立即返回。缺点:非阻塞IO立即返回并不是业务层期望的数据,而仅仅是调用的状态,为了获取完整的数据,应用程序需要重复调用IO操作确认,即轮询。

轮询

常见的三种轮询方式:select、poll和epoll。

1、select

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

参数解释

  • nfds:被监听的文件描述符总数
  • readfds writefds exceptfds : 可读、可写、异常事件的accept到对应的文件描述符集合
  • fd_set:是一个整形数组,每一个元素的每一位来表示每一个文件描述符是否有相应的事件发生。(0没有1有)数组的长度由FD_SETSIZE决定
  • timeout:轮询的时间片

通过设置或者检查存放fd(文件标识符)标志位的数据结构进行处理(select对应于内核的sys_select调用):1.将第2、3、4个参数指向的fd_set拷贝到内核;2.对每个被set对描述符调用进行poll,并记录在临时结果中(fdset)

缺点是:

  • 单个进程的fd监视数量有限
  • 需要维护一个存放fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大
  • 每次select操作需要初始化fdset,因为select的第2、3、4参数既是输入参数也是输出参数,在内核中会被修改
  • socker的扫描是线性扫描

2、poll

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

poll和select的实现机制类似,对应内核的sys_poll,但是传递的是pollfd数组,接着对pollfd数组进行poll。

优点:

  • pollfd数组只需要被初始化一次,因为pollfd的events字段和revents分别用于标示关注的事件和发生的事件
  • 对描述符个数没有限制,poll通过一个pollfd数组向内核传递需要关注的事件

3、epoll

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

相对于select和poll的遍历查询,epoll是真实利用了执行回调和事件通知的机制,充分利用CPU,因此效率比较高。

4、总结

总的来说,轮询技术满足非阻塞IO确保完整数据获取的需求,当时对于应用程序来说,它仍然是同步,因为它必须等待IO完全返回。等待IO期间,CPU要么遍历文件描述符的状态,要没用于休眠等待事件发生。

二、同步&异步

同步IO:同步IO比较简单,就是简单的顺序执行,其实阻塞和非阻塞都属于同步IO。

异步IO:这里拿Node举例,在Node中,我们知道异步是它的一大特色,那它到底有哪些好处呢?

  • 1、从请求时间上来说,假设某个资源需要获取a,b两个地方的资源,a资源需要时间M毫秒,b资源需要时间N毫秒,此时:同步需要sum(M,N),异步需要max(M,N)
  • 2 从资源消耗来说,异步远离阻塞,单线程避免了多线程容易出现的死锁等各种异常情况

我们期待的异步是:当我们应用程序发起阻塞请求,不需要轮询技术,直接处理下一个任务;当阻塞请求完成之后,将数据传递到应用程序。在Linux下存在这种异步IO即AIO。

如果我们自己去实现异步IO,则可以通过线程池+轮询技术来实现数据的获取。例如现在应用程序发起了一个阻塞请求,我们可以如下处理:

  1. 让a线程利用轮询技术去处理阻塞调用
  2. 让b线程去执行计算处理
  3. 当a线程的处理结果通过线程间共享发送给b
  4. 这样,就完成了异步IO。

三、总结

通过上面的介绍,我们需要知道的是:阻塞&非阻塞和异步&同步是不能混为一谈的,非阻塞本质上还是同步,它所谓的返回只是状态并不是数据。

由于阻塞&非阻塞和异步&同步的概念十分类似,这里就其做了一个简单介绍

进程| 线程 | 阻塞 | 阻塞&非阻塞 和 同步&异步的更多相关文章

  1. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...

  2. GIL全局解释器锁,线程池与进程池 同步异步,阻塞与非阻塞,异步回调

    GIL全局解释器锁 1.什么是GIL 官方解释:'''In CPython, the global interpreter lock, or GIL, is a mutex that prevents ...

  3. 4月27日 python学习总结 GIL、进程池、线程池、同步、异步、阻塞、非阻塞

    一.GIL:全局解释器锁 1 .GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在解释器身上的, 同一个进程内的所有线程都需要先抢到GIL锁,才能执行解释器代码 2.GIL的优缺点: 优点:  保 ...

  4. python全栈开发day31-操作系统介绍,异步、同步、阻塞、非阻塞,进程

    一.网络编程内容回顾 1.arp协议 #交换机 #广播.单播 2.ip协议 3.tcp和udp协议 tcp:可靠的,面向连接的,字节流传输,长连接 三次握手:一方发送请求,另一方确认请求同时发送请求, ...

  5. UDP协议,多道技术,进程,同步与异步,阻塞与非阻塞

    UDP协议 简介 UDP叫做用户数据报协议,是OSI七层参考模型中传输层使用的协议,他提供的是不可靠传输,既它在传输过程 中不保证数据的完整性! 端口号 UDP使用IP地址和端口号进行标识,以此将数据 ...

  6. 简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

    1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分 ...

  7. 同步与异步 & 阻塞与非阻塞

    在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 一.同步 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用 ...

  8. python学习笔记-(十四)I/O多路复用 阻塞、非阻塞、同步、异步

    1. 概念说明 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方).操作系统的核心是内核,独立于普通的应用程序,可 ...

  9. socket阻塞与非阻塞,同步与异步、I/O模型,select与poll、epoll比较

    1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步:      所谓同步,就 ...

  10. socket阻塞与非阻塞,同步与异步

    socket阻塞与非阻塞,同步与异步 作者:huangguisu 转自:http://blog.csdn.net/hguisu/article/details/7453390 1. 概念理解 在进行网 ...

随机推荐

  1. goroutine的设计与实现

    goroutine背后的系统知识 http://www.sizeofvoid.net/goroutine-under-the-hood/ 下周写完

  2. Jupyter notebook部署引导

    一.简介方面很多博客写得比较好,主要转发几篇: 1.对Jupyter notebook 的整体进行介绍: https://www.itcodemonkey.com/article/6025.html ...

  3. PAT Basic 1069 微博转发抽奖 (20 分)

    小明 PAT 考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔 N 个人就发出一个红包.请你编写程序帮助他确定中奖名单. 输入格式: 输入第一行给出三个正整数 M(≤ 1000). ...

  4. C#自由组合本地缓存、分布式缓存和数据库的数据

    一.背景介绍: 我们在进行数据存储的时候,有时候会加入本地缓存.分布式缓存以及数据库存储三级的结构,当我们取值的时候经常是像下面这样的流程: 1.先取本地缓存,如果值存在直接返回 2.本地缓存不存在, ...

  5. CDN加速地址URL拿不到,显示“无法访问此网站”

    问题:CDN加速地址URL拿不到,显示“无法访问此网站” 原因:浏览器缓冲原因,导致拿到的content-encoding不是一个标准的值 解决方法: 1. 客户机器 ping一下访问的CDN加速域名 ...

  6. linux目录太长怎么办?分享一点小技巧

    在linux使用cd的时候,可能会遇到目录比较深的时候,这个时候总是cd一个很长的目录会很麻烦,那有没有什么比较方便的方法呢? 若是在两个目录中来回切换,这个时候可以使用cd - 这个命令,可以完成在 ...

  7. 《流畅的Python》Data Structures--第7章 colsure and decorator

    Function Decorators and Closures 装饰器是用于增强函数的行为,理解它,就必须先理解闭包. Python3引入关键字nonlocal,如果要理解闭包,就必须了解它的所有方 ...

  8. mysql查询表中最后一条记录

    查询全部的记录:            select * from test_limit ; 查第一条记录:             select * from test_limit limit 1; ...

  9. python_面向对象——对象之间的关联关系

    1.将类中的对象关联起来(简单的方法) class Person: def __init__(self,name,age,sex): self.name = name self.age = age s ...

  10. SQL 删除重复记录,只保留一条记录

    DELETE FROM py_bond_shenzhen_exchange_opinion_2_1 WHERE id NOT IN (SELECT id FROM (SELECT min(id) AS ...