python io多路复用框架_python中IO多路复用、协程

一、IO多路复用

IO多路复用:检测多个socket是否已经发生变化(是否已经连接成功/是否已经获取数据)(可读/可写)

importsocketdefget_data(key):

client=socket.socket()

client.setblocking(False)#将原阻塞的位置变成非阻塞

try:

client.connect(("www.baidu.com",80)) #因为没有等待所以会报错

exceptBlockingIOError as e:passclient.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 notdata:breakdata_list.append(data)

data= b"".join(data_list)print(data.decode("utf8"))

key_list= ["alex","sb","db"]for item inkey_list:

get_data(item)

View Code

二、基于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 inv:print(item.append(1))#以后

classFoo(object):def __init__(self,data):

self.data=datadefappend(self,ietm):

self.data.appded(item)

v= [[11,22],[33,44],[55,66]]for item inv:print(item.append(1))

面向对象的思想

三、协程

概念:

进程、操作系统中存在

线程、操作系统中存在

协程、是由程序员创造出来的一个不是真实存在的东西

协程:是微线程,是对一个线程进行分片,使得线程在代码块之间来回切回执行,而不是在原来逐行执行

importgreenletdeff1():print(11)

gr2.switch()print(22)

gr2.switch()deff2():print(33)

gr1.switch()print(44)#协程gr1

gr1 =greenlet.greenlet(f1)#协程gr2

gr2 =greenlet.greenlet(f2)

gr1.switch()

View Code

注:单纯用协程无用

协程+遇到IO就切换,才真的有用  pip3 install gevent

importgeventfrom gevent importmonkey

monkey.patch_all()importrequestsdefget_page1(url):

ret=requests.get(url)print(url,ret.content)defget_page2(url):

ret=requests.get(url)print(url,ret.content)defget_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/')

])

View Code

总结:

1什么是协程:

协程也可以成为微线程,基石开发者控制线程执行流程,控制先执行某段代码然后在切换到另外函数执行代码

2.协程可以提高并发么

协程自己本身无法实现并发(甚至性能会降低)

协程+IO切换性能提高

3.进程、线程、协程的区别

4.单线程提高并发:

协程+IO切换:gevent

基于事件循环的异步非阻塞框架:Twisted

twisted

from twisted.web.client importgetPage, deferfrom twisted.internet importreactordefall_done(arg):

reactor.stop()defcallback(contents):print(contents)

deferred_list=[]

url_list= ['http://www.bing.com', 'http://www.baidu.com', ]for url inurl_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()

View Code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值