python中IO多路复用、协程
一、IO多路复用
IO多路复用:检测多个socket是否已经发生变化(是否已经连接成功/是否已经获取数据)(可读/可写)
import socket
def get_data(key):
client = socket.socket()
client.setblocking(False) #将原阻塞的位置变成非阻塞
try:
client.connect(("www.baidu.com",80)) #因为没有等待所以会报错
except BlockingIOError as e:
pass
client.sendall(b"GET /s?wd=%s HTTP/1.0\r\nhost:www.baidu.com\r\n\r\n" %key)
data_list = []
while 1:
data = client.recv(8096)
if not data:
break
data_list.append(data)
data = b"".join(data_list)
print(data.decode("utf8"))
key_list = ["alex","sb","db"]
for item in key_list:
get_data(item)
二、基于IO多路复用+socket实现并发请求
IO多路复用
socket非阻塞
基于事件循环实现的异步非阻塞框架
非阻塞:不等待
异步:执行完某个人物后自动调用我给他的函数。
Python中开源 基于事件循环实现的异步非阻塞框架 Twisted
总结:
1. socket默认是否是阻塞的?阻塞体现在哪里?
是,connect、accept、recv
2. 如何让socket编程非阻塞?
setblocking(False)
3. IO多路复用作用?
检测多个socket是否发生变化。
操作系统检测socket是否发生变化,有三种模式:
select:最多1024个socket;循环去检测。
poll:不限制监听socket个数;循环去检测(水平触发)。
epoll:不限制监听socket个数;回调方式(边缘触发)。
Python模块:
select.select
select.epoll
4. 提高并发方案:
- 多进程
- 多线程
- 异步非阻塞模块(Twisted) scrapy框架(单线程完成并发)
5. 什么是异步非阻塞?
- 非阻塞,不等待。
比如创建socket对某个地址进行connect、获取接收数据recv时默认都会等待(连接成功或接收到数据),才执行后续操作。
如果设置setblocking(False),以上两个过程就不再等待,但是会报BlockingIOError的错误,只要捕获即可。
- 异步,通知,执行完成之后自动执行回调函数或自动执行某些操作(通知)。
6. 什么是同步阻塞?
- 阻塞:等
- 同步:按照顺序逐步执行
key_list = ['alex','db','sb']
for item in key_list:
ret = requests.get('https://www.baidu.com/s?wd=%s' %item)
print(ret.text)
7.概念
#以前
v = [[11,22],[33,44],[55,66]] #每一个都有一个append方法
for item in v:
print(item.append(1))
#以后
class Foo(object):
def __init__(self,data):
self.data = data
def append(self,ietm):
self.data.appded(item)
v = [[11,22],[33,44],[55,66]]
for item in v:
print(item.append(1))
面向对象的思想
三、协程
概念:
进程、操作系统中存在
线程、操作系统中存在
协程、是由程序员创造出来的一个不是真实存在的东西
协程:是微线程,是对一个线程进行分片,使得线程在代码块之间来回切回执行,而不是在原来逐行执行
import greenlet
def f1():
print(11)
gr2.switch()
print(22)
gr2.switch()
def f2():
print(33)
gr1.switch()
print(44)
#协程gr1
gr1 = greenlet.greenlet(f1)
#协程gr2
gr2 = greenlet.greenlet(f2)
gr1.switch()
注:单纯用协程无用
协程+遇到IO就切换,才真的有用 pip3 install gevent
import gevent
from gevent import monkey
monkey.patch_all()
import requests
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/'),
gevent.spawn(get_page2, 'https://www.yahoo.com/'),
gevent.spawn(get_page3, 'https://github.com/')
])
总结:
1什么是协程:
协程也可以成为微线程,基石开发者控制线程执行流程,控制先执行某段代码然后在切换到另外函数执行代码
2.协程可以提高并发么
协程自己本身无法实现并发(甚至性能会降低)
协程+IO切换性能提高
3.进程、线程、协程的区别
4.单线程提高并发:
协程+IO切换:gevent
基于事件循环的异步非阻塞框架:Twisted
twisted
from twisted.web.client import getPage, defer
from twisted.internet import reactor def all_done(arg):
reactor.stop() def callback(contents):
print(contents) deferred_list = []
url_list = ['http://www.bing.com', 'http://www.baidu.com', ]
for url in url_list:
deferred = getPage(bytes(url, encoding='utf8'))
deferred.addCallback(callback)
deferred_list.append(deferred) dlist = defer.DeferredList(deferred_list)
dlist.addBoth(all_done) reactor.run()
python中IO多路复用、协程的更多相关文章
- Python异步IO之协程(一):从yield from到async的使用
引言:协程(coroutine)是Python中一直较为难理解的知识,但其在多任务协作中体现的效率又极为的突出.众所周知,Python中执行多任务还可以通过多进程或一个进程中的多线程来执行,但两者之中 ...
- Python IO 多路复用 \协程
IO 多路复用 作用: 检测多个socket是否已经发生变化(是否已经连接成功/是否已经获取数据) 即(可读/可写) IO请求时 解决并发 : 单线程 def get_data(key): cl ...
- IO多路复用,协程
https://www.cnblogs.com/wangjun187197/p/9642429.html Python之路--协程/IO多路复用 I/O复用模型 此模型用到select和poll函数, ...
- Python异步IO之协程(二):使用asyncio的不同方法实现协程
引言:在上一章中我们介绍了从yield from的来源到async的使用,并在最后以asyncio.wait()方法实现协程,下面我们通过不同控制结构来实现协程,让我们一起来看看他们的不同作用吧- 在 ...
- python中线程 进程 协程
多线程:#线程的并发是利用cpu上下文的切换(是并发,不是并行)#多线程执行的顺序是无序的#多线程共享全局变量#线程是继承在进程里的,没有进程就没有线程#GIL全局解释器锁#只要在进行耗时的IO操作的 ...
- Python中进程线程协程小结
进程与线程的概念 进程 程序仅仅只是一堆代码而已,而进程指的是程序的运行过程.需要强调的是:同一个程序执行两次,那也是两个进程. 进程:资源管理单位(容器). 线程:最小执行单位,管理线程的是进程. ...
- python中普通函数调用协程
import asyncio def target(loop, timeout=None): future = asyncio.run_coroutine_threadsafe(add(1, b=2) ...
- python进阶——进程/线程/协程
1 python线程 python中Threading模块用于提供线程相关的操作,线程是应用程序中执行的最小单元. #!/usr/bin/env python # -*- coding:utf-8 - ...
- 进程&线程(三):外部子进程subprocess、异步IO、协程、分布式进程
1.外部子进程subprocess python之subprocess模块详解--小白博客 - 夜风2019 - 博客园 python subprocess模块 - lincappu - 博客园 之前 ...
随机推荐
- 16、vue引入echarts,划中国地图
vue引入echarts npm install echarts --save main.js引入 import echarts from 'echarts' Vue.prototype.$echar ...
- Swoole练习 TCP
TCP <?php $serv = new swoole_server("127.0.0.1", 9501); //监听连接进入事件 $serv->on('connec ...
- 解决jQuery版本冲突
解决jquery版本冲突问题 <!-- 引入1.6.4版的jq --><script src="http://ajax.googleapis.com/ajax/libs/j ...
- Deepin 15.11 install nvidia dirver[mei you an zhuang shu ru fa]
1.firstly, exec: sudo vim /etc/modprobe.d/blacklist-nouveau.conf[create], and input [blacklist nouve ...
- [Oracle] - 使用 EXP / IMP 对数据库进行备份与还原
只有Oracle客户端环境,如何完整备份数据库? 方法1:在本地搭建与目标环境相同版本的服务端,远程访问执行导出命令.这种方式远程备份速度较慢(VPN环境下测试). 方法2:登陆客户端,先导出数据库表 ...
- 面向对象分析与设计—OOA部分
第二部分 面向对象分析 2.1 面向对象分析(OOA)的定义? OOA——面向对象的分析,就是运用面向对象方法进行系统分析,对问题域(问题所涉及的范围)和系统责任(所开发的系统应具备的职能)进行分析与 ...
- python 之 面向对象基础(组合和封装)
7.4 组合 解决类与类之间代码冗余问题有两种解决方案: 1.继承:描述的是类与类之间,什么是什么的关系 2.组合:描述的是类与类之间的关系,是一种什么有什么的关系 一个类产生的对象,该对象拥有一个属 ...
- Spring的事件监听ApplicationListener
ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制. 如果容器中存在Applica ...
- sqlserver exists 与 in 的区别
使用 EXISTS 方式 select * from A a where EXISTS(select b.mainInfoId from B b where b.mainInfoId=a.main ...
- typescript 入门教程四
ts中的function和接口 interface PrintCallback{ // 匿名函數,返回类型为空 (success:boolean):void } interface Person{ / ...