1. IO多路复用
IO多路复用作用:检测多个socket是否已经发生变化(是否已经连接成功/是否已经获取数据)(可读/可写)
2. 基于IO多路复用+socket实现并发请求(一个线程100个请求)
IO多路复用 socket非阻塞
基于事件循环实现的异步非阻塞框架:lzl
非阻塞:不等待
异步:执行完某个人物后自动调用我给他的函数。
Python中开源 基于事件循环实现的异步非阻塞框架 Twisted
3.IO多路复用作用?
检测多个socket是否发生变化。
操作系统检测socket是否发生变化,有三种模式:
select:最多1024个socket;循环去检测。
poll:不限制监听socket个数;循环去检测(水平触发)。
epoll:不限制监听socket个数;回调方式(边缘触发)。
Python模块:
select.select
select.epoll
4.提高并发方案 :
多进程
多线程
异步非阻塞模块 (Twisted) scrapy框架(单线程完成并发)的大V大V
5.什么是异步非阻塞?
非阻塞 , 不等待
比如创建socket对某个地址进行connect、获取接收数据recv时默认都会等待(连接成功或接收到数据),才执行后续操作。
如果设置setblocking(False),以上两个过程就不再等待,但是会报BlockingIOError的错误,只要捕获即可。
异步,通知,执行完成之后自动执行回调函数或自动执行某些操作(通知)。
比如做爬虫中向某个地址baidu.com发送请求,当请求执行完成之后自执行回调函数。
6.什么是同步阻塞 ?
阻塞 : 等
同步 : 按照顺序逐步执行
3. 协程
感念 :
进程 , 操作系统中不存在
线程 , 操作系统中不存在
协程 , 是由程序员创造出来的一个不是真实存在的东西
协程 : 是微线程,对一个线程进程分片 , 使得线程在代码块之间来回切换执行 , 而不是在原来逐行执行 。
注意 : 单纯的协程无用
协程 + 遇到IO就切换 pip3 install gevent
代码中遇到 IO 都会自动执行 greenlet 的switch 进行切换
from gevent import monkey monkey.patch_all() # 以后代码中遇到IO都会自动执行greenlet的switch进行切换 import requests import gevent def get_page1(url): ret = requests.get(url) print(url,ret.content) def get_page2(url): ret = requests.get(url) print(url,ret.content) def get_page3(url): ret = requests.get(url) print(url,ret.content) gevent.joinall([ gevent.spawn(get_page1, 'https://www.python.org/'), # 协程1 gevent.spawn(get_page2, 'https://www.yahoo.com/'), # 协程2 gevent.spawn(get_page3, 'https://github.com/'), # 协程3 ])
1.什么是协程 :
协程可以称为"微线程" , 就是开发者控制线程执行流程 , 控制先执行某段代码然后在切换到另外执行代码....来回切换
2.协程可以提高并发吗 :
协程自己本身无法实现并发(可能性能会降低)
协程 + IO切换性能高
3.单线程提供并发 :
协程 IO 切换 (gevent)
基于事件循坏的异步非阻塞框架 : Twisted
手动实现协程 : yield关键字生成器
def f1(): print(11) yield print(22) yield print(33) def f2(): print(55) yield print(66) yield print(77) v1 = f1() v2 = f2() next(v1) # v1.send(None) next(v2) # v1.send(None) next(v1) # v1.send(None) next(v2) # v1.send(None) next(v1) # v1.send(None) next(v2) # v1.send(None)
4. 进程 , 线程 , 协程的区别 ?
进程 :是资源分配的最小单元 , 其作用是进行数据隔离 ,
线程 :是cpu调度的最小单元 , 其作用主要是执行某个任务,
后来程序员为了让代码更牛逼 , 创建了协程 , 协程本身不存在 , 是程序员自己创造出来的 ,
协程 : 可以对代码的执行顺序进行控制 , 本身协程存在没有意义 , 但是协程要是和IO放在一起 就很牛逼。
遇到IO操作就切换 , 相当于把一个线程分片 , 所达到的效果是线程一直没有停 , 一直在工作 ,
这就是进程 , 线程 , 协程 , 的本质区别 , 在python中用协程的时候会有一个模块叫greenlet ,
协程加IO自动切换的模块叫gevent
一个应用程序可以有多个进程 , 一个进程可以有多个线程 ,
其他语言几乎很少用进程 , 都是用线程 ,
对于python来说 : IO操作主要用多线程实现 , 计算密集型操作主要是用多进程实现 。
主要原因 : python中存在GIL锁 , GIL锁的作用就是保证一个进程中同一时刻只有一个线程被cpu调度
所以在python中想要利用cpu的多核优势就是开多个进程 。
5.异步非阻塞
6.IO多路复用
作用: 可以监听所有的IO请求状态 。
三种模式 :
select
poll
epoll