gj12-1 协程和异步io

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

并发、并行

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

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

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

问题-喝茶

同步、异步

同步是指代码调用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好

原文地址:https://www.cnblogs.com/wenyule/p/10315783.html

时间: 2024-10-27 17:30:31

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

python的协程和异步io【select|poll|epoll】

协程又叫做微线程,协程是一种用户态的轻量级的线程,操作系统根本就不知道协程的存在,完全由用户来控制,协程拥有自己的的寄存器的上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回来后,恢复之前保存的寄存器的上下文关系,因此协程能保留上一次调用的状态,每次过程重入的时候,就相当于进入上一次调用的状态 协程一定在单线程中,协程的切换是在线程中切换,和单个线程在cpu之间不停的切换是一样的但是线程切换是cpu控制的,而协程的切换是用户控制的,操作系统根本无感知:协程的切换比线程的切换速

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

协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程,协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切换回来的时候,恢复先前保存的寄存器上下文和栈.因此,协程能保留上一次调用的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法,进入上一次离开时所处逻辑流的位置. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返

协程、异步IO

协程,又称微线程,纤程.英文名Coroutine,协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈.因此: 协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置. 协程的好处: 无需线程上下文切换的开销 无需原子操作锁定及同步的开销 "原子操作(atomic operation)是不需要s

协程,异步IO

协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程.实现单线程的并发. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈.因此: 协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置. 协程的好处: 无需线程上下文切换的开销 无需原子操作锁定及同步的开销(协程本身就

8-3:协程、异步IO、数据库、rabbitMQ队列、redis缓存

https://www.cnblogs.com/alex3714/articles/5248247.html 本节内容 1.Gevent协程 2.Select\Poll\Epoll异步IO与事件驱动 3.Python连接Mysql数据库操作 4.RabbitMQ队列 5.Redis\Memcached缓存 6.Paramiko SSH 7.Twsited网络框架 原文地址:https://www.cnblogs.com/chenhuan123/p/12038657.html

进程,线程,协程,异步IO知识点

进程: qq 要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,内存的管理,网络接口的调用等...对各种资源管理的集合 就可以成为  进程 线程: 是操作系统最小的调度单位, 是一串指令的集合 进程 要操作cpu , 必须要先创建一个线程  ,all the threads in a process have the same view of the memory所有在同一个进程里的线程是共享同一块内存空间的 A thread线程 is an execution执行 context

队列,生产者消费者模型,协程,异步IO

Alex本期相关博文. Python中的Priority Queue是minimal priority queue. Queue使用task_done与join实现生产者与消费者的通信. Queue只能用于一个进程的各个线程的同步.

Python实现基于协程的异步爬虫

一.课程介绍 1. 课程来源 本课程核心部分来自<500 lines or less>项目,作者是来自 MongoDB 的工程师 A. Jesse Jiryu Davis 与 Python 之父 Guido van Rossum.项目代码使用 MIT 协议,项目文档使用 http://creativecommons.org/licenses/by/3.0/legalcode 协议. 课程内容在原文档基础上做了稍许修改,增加了部分原理介绍,步骤的拆解分析及源代码注释. 2. 内容简介 传统计算机

swoole与php协程实现异步非阻塞IO开发

“协程可以在遇到阻塞的时候中断主动让渡资源,调度程序选择其他的协程运行.从而实现非阻塞IO” 然而php是不支持原生协程的,遇到阻塞时如不交由异步进程来执行是没有任何意义的,代码还是同步执行的,如下所示: function foo() { $db=new Db(); $result=(yield $db->query()); yield $result; } 上面的数据库查询操作是阻塞的,当调度器调度该协程到这一步时发现执行了阻塞操作,此时调度器该怎么办?选择其余协程执行?那该协程的阻塞操作又该