协程
Coroutine,用户自己控制的轻量级线程
好处:
无须线程上下文切换的开销
无须院子操作锁定和同步的开销
方便切换控制流,简化编程模型
高并发,高扩展,低成本
缺点:
无法利用多核资源
遇到IO操作就切换下一个协程
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # -*- Author:Hinimix -*-
# yield实现类似效果 def consumer(name): print("start eating baozi") while True: new_baozi = yield print("%s is eating baozi %s" % (name, new_baozi)) def producer(): conn1.__next__() conn2.__next__() n = 0 while n < 5: conn1.send(n) conn2.send(n) print("making baozi, ", n) n += 1 if __name__ == '__main__': conn1 = consumer('hinimix') conn2 = consumer('annie') p = producer()
greenlet 协程
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # -*- Author:Hinimix -*- from greenlet import greenlet # 封装好的协程库 # gevent是对greenlet再次封装而成的,可以自动切换协程 def t1(): print(12) gr2.switch() print(34) gr2.switch() def t2(): print(56) gr1.switch() print(78) gr1 = greenlet(t1) gr2 = greenlet(t2) gr1.switch()
gevent
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # -*- Author:Hinimix -*- import gevent def t1(): print('in t1') gevent.sleep(2) print('done t1') def t2(): print('in t2') gevent.sleep(.5) print('done t2') def t3(): print('in t3') gevent.sleep(0) print('done t3') gevent.joinall([ gevent.spawn(t1), gevent.spawn(t2), gevent.spawn(t3) ])
gevent并行和串行对比
并行:
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # -*- Author:Hinimix -*- import urllib.request import gevent from gevent import monkey import time monkey.patch_all() #把当前程序所有的IO单独做标记 def get_url(url): print('get url %s' % url) response = urllib.request.urlopen(url) print('done! size: ', len(response.read())) return response.read() # print(get_url("https://blog.csdn.net/woainishifu/article/details/76105667")) atime = time.time() gevent.joinall([ gevent.spawn(get_url, 'https://blog.csdn.net/woainishifu/article/details/76105667'), gevent.spawn(get_url, 'http://www.sina.com.cn/'), gevent.spawn(get_url, 'https://www.openssl.org/source/') ]) btime = time.time() print(btime-atime)
串行:
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # -*- Author:Hinimix -*- import urllib.request import gevent import time def get_url(url): print('get url %s' % url) response = urllib.request.urlopen(url) print('done! size: ', len(response.read())) return response.read() list_address = [ 'https://blog.csdn.net/woainishifu/article/details/76105667', 'http://www.sina.com.cn/', 'https://www.openssl.org/source/', ] # print(get_url("https://blog.csdn.net/woainishifu/article/details/76105667")) atime = time.time() for i in list_address: get_url(i) btime = time.time() print(btime-atime)