1 并发、并行、同步、异步、阻塞、非阻塞

并发、并行

并发是报一个时间段内有几个程序在同一个cpu上运行,但是任意时刻只有一个程序在cpu上运行。在一个时间段内某一个请求很快,能够响应的用户就越多,高并发。

并行是指任意时刻点上,有多个程序同时运行在多个cpu上,并行数量跟CPU数一致的,因此没有高并行。

情况:开水没有:水壶要洗,茶壶茶杯要洗:火生了,茶叶也有了。怎么办?
时间分配:
洗水壶:
灌凉水:
洗茶壶:
洗茶杯:
拿茶叶:
泡茶:
烧开水:
并发版
老张
办法甲:洗好水壶,灌上凉水,放在火上;在等待水开的时间里,洗茶壶、洗茶杯、拿茶叶;等水开了,泡茶喝。
总用时:+++=
办法乙:先做好一些准备工作,洗水壶,洗茶壶茶杯,拿茶叶;一切就绪,灌水烧水;坐待水开了泡茶喝。
总用时:+++++=
办法丙:洗净水壶,灌上凉水,放在火上,坐待水开;水开了之后,急急忙忙找茶叶,洗茶壶茶杯,泡茶喝。
总用时:+++++=
并行版
老张:洗好水壶,灌上凉水,放在火上
老李:洗茶壶
老谢:洗茶杯

问题-喝茶

同步、异步

同步是指代码调用IO操作时,必须等待IO操作完成才返回的调用方式。
异步是指代码调用IO操作时,不必等IO操作完成就返回的调用方式。

消息通信 的一种机制

阻塞、非阻塞

阻塞是指调用函数时候当前线程被挂起。
阻塞是指调用函数时候当前线程不会被挂起,而是立即返回。

是函数调用的一种机制

2 IO 多路复用 (select、poll 和 epoll)

C10K问题

C10k是一个在1999年被提出来的技术挑战
如何在一颗 1GHz CPU,2G内存,1gbps网络环境下,让单台服务器同时
为1万个客户端提供FTP服务

多用户连接,多线程一个线程只能处理一个socket,不能处理上万用户,因为不可能开启上万线程。

Unix下五种I/O模型

阻塞式I/O
非阻塞式I/O
I/O复用
信号驱动式I/O(使用较少)
异步I/O(POSIX的aio系列函数)

阻塞式I/O

recvfrom 会一直阻塞,直到返回数据

client.setblocking(False) #socket 中设置非阻塞
client.connect((host,80))

非阻塞式I/O

没有数据准备好就立马返回

如果下一行代码,依赖上一句(connect的建立)完成,就需要不断的while循环去检查状态(是耗cpu的),时间和同步差不多。

如果下一行代码,不依赖上一句代码的执行完成,如做计算任务或者再次发起其他的连接请求,非阻塞IO就很有用

将数据从内核复制到用户空间

I/O复用

I/O多路复用,很多框架用的

select 也是阻塞的,可以同时监听多个文件句柄 socket 状态。一旦有一个发生变化,就处理它,没有去轮询。 但 recvfrom 复制数据报,将数据从内核复制到用户空间时仍需要耗费时间。

信号驱动式IO

用的比较少

异步IO

真正意义上的异步IO,

数据准备好了才发信号处理,省略了将数据从内核复制到用户空间的等待时间,编程难度较大。对比io多路复用,性能提高不明显

select、poll、epoll

select,poll,epoll都是IO多路复用的机制。I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程(将数据从内核复制到用户空间)是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。

select

select函数监视的文件描述符分3类,分别是writefds、readfds、和exceptfds。调用后select函数会阻塞,直到有描述副就绪(有数据可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以通过遍历fdset,来找到就绪的描述符。
select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点。select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但是这样也会造成效率的降低。

poll

不同与select使用三个位图来表示三个fdset的方式,poll使用一个pollfd的指针实现。
pollfd 结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式。同时,pollfd并没有最大数量限制(但是数量过大后性能也是会下降)。和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。
  从上面看,select和poll都需要在返回后,通过遍历文件描述符来获取已经就绪的socket。事实上,同时连接的大量客户端在一时刻可能只有很少的处于就绪状态,因此随着监视的描述符数量的增长,其效率也会线性下降

epoll

epol是在linux 2.6内核中提出的,是之前的 select 和 poll 的增强版本。相对于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。  (nginx)

查询利用了:红黑树

并不代表 epoll 比 select 一定好

# 1. epoll 并不代表一定比 select 好
# 在并发高的情况下,连接活跃度不是很高, epoll 比 select
# 并发性不高,同时连接很活跃, select 比 epoll好

gj12-1 协程和异步io的更多相关文章

  1. 第十一章:Python高级编程-协程和异步IO

    第十一章:Python高级编程-协程和异步IO Python3高级核心技术97讲 笔记 目录 第十一章:Python高级编程-协程和异步IO 11.1 并发.并行.同步.异步.阻塞.非阻塞 11.2 ...

  2. Python-09-线程、进程、协程、异步IO

    0. 什么是线程(thread)? 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆 ...

  3. 协程、异步IO

    协程,又称微线程,纤程.英文名Coroutine,协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器 ...

  4. python 自动化之路 day 10 协程、异步IO、队列、缓存

    本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 RabbitMQ队列 Redis\Memcached缓存 Paramiko SSH Twsited网络框架 引子 到目 ...

  5. Python【第十篇】协程、异步IO

    大纲 Gevent协程 阻塞IO和非阻塞IO.同步IO和异步IO的区别 事件驱动.IO多路复用(select/poll/epoll) 1.协程 1.1协程的概念 协程,又称微线程,纤程.英文名Coro ...

  6. Day10 - Python协程、异步IO、redis缓存、rabbitMQ队列

    Python之路,Day9 - 异步IO\数据库\队列\缓存   本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitM ...

  7. Python开发【第九篇】:协程、异步IO

    协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程,协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回 ...

  8. 协程和异步io

    一. 并发.并行.同步.异步.阻塞.非阻塞 1.并发:是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机(CPU)上运行,但任一个时刻点上只有一个程序在处理机上运 ...

  9. Python 10 协程,异步IO,Paramiko

    本节内容 Gevent协程 异步IO Paramiko 携程 协程,又称为微线程,纤程(coroutine).是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文 ...

  10. Python协程、异步IO

    本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko SS ...

随机推荐

  1. 前端-javascript-正则表达式

    1.概念 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <titl ...

  2. Windows窗体技术

    Windows窗体技术 Winform例子下载 https://pan.baidu.com/s/1zXO8gVuFAeKQ_Tnz55A4VQ  密码:i1r6

  3. vue深入了解组件——组件注册

    一.组件名 在注册一个组件的时候,我们始终需要给它一个名字.比如在全局注册的时候我们已经看到了: Vue.component('my-component-name', { /* ... */ }) J ...

  4. centos升级python2.7

    http://meiyitianabc.blog.163.com/blog/static/10502212720133192489840/

  5. 为什么要在linux命令前加上 ./

    为什么要在linux命令前加上 ./ ? 简述 执行unix或linux中除了path系统变量外的目录下的命令都要加./. 修改用户的 .bash_profile,在 PATH一行最后加上 “:.” ...

  6. Haskell语言学习笔记(38)Lens(1)

    Lens Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值. view, over, set Prelude> :m +Control.Lens P ...

  7. nstall neovim on Ubuntu 16.04

    https://neovim.io/ To install NeoVim on Ubuntu, run 1 2 3 sudo add-apt-repository ppa:neovim-ppa/sta ...

  8. CTR点击率预估干货分享

    CTR点击率预估干货分享 http://blog.csdn.net/bitcarmanlee/article/details/52138713

  9. Python 遍历文件夹 listdir walk 的区别

    一.一级目录import os path = 'd:\file'; for filename in os.listdir(path): print(os.path.join(path,filename ...

  10. Web标准:五、超链接伪类

    Web标准:五.超链接伪类 知识点: 1.链接的四种样式 2.将链接转换为块状 3.用css制作按钮 4.首字下沉   1)链接的四种样式 超链接有四个伪类,分别是: a:link 未访问的链接 a: ...