如何实现两个函数之间的切换呢,在之前我们可以这样实现:
def func(): print(1) yield print(3) yield def fu(): a=func() next(a) print(2) next(a) print(4) fu() C:UsershcAppDataLocalProgramsPythonPython36python3.exe C:/s9/day40/40.py 1 2 3 4 Process finished with exit code 0
使用这种方法写一个生产者消费者模型
def func(): while 1: n=yield print('吃%s包子'%n) def fun(): a=func() next(a) for i in range(10): print('包子%s熟了'%i) a.send(i) fun() C:UsershcAppDataLocalProgramsPythonPython36python3.exe C:/s9/day40/40.py 包子0熟了 吃0包子 包子1熟了 吃1包子 包子2熟了 吃2包子 包子3熟了 吃3包子 包子4熟了 吃4包子 包子5熟了 吃5包子 包子6熟了 吃6包子 包子7熟了 吃7包子 包子8熟了 吃8包子 包子9熟了 吃9包子 Process finished with exit code 0
如何在单线程中切换呢?这个时候我们需要引用一个模块
greenlet
执行后看不到效果,是因为太快了,快到来不及打印,所以,我们让它睡一会就好了,
from greenlet import greenlet import time def func(): print('对8') f1.switch() time.sleep(1) print('对9') f1.switch() def fu(): print('三带一') f.switch() time.sleep(1) print('王炸') f=greenlet(func) f1=greenlet(fu) f.switch() C:UsershcAppDataLocalProgramsPythonPython36python3.exe C:/s9/day40/40.py 对8 三带一 对9 王炸 Process finished with exit code 0
在代码之间来回切换会降低效率
另外,在yield,greenlet中,切换不能规避IO时间:
如果想要规避IO时间,又要使用一个模块:gevevnt
下面这是gevent版本的实现切换功能:
from gevent import monkey;monkey.patch_all() import time import gevent def func(): print('11') gevent.sleep(2) print('33') def fu(): print('22') gevent.sleep(2) print('44') g=gevent.spawn(func) g1=gevent.spawn(fu) gevent.joinall([g,g1]) C:UsershcAppDataLocalProgramsPythonPython36python3.exe C:/s9/day40/40.py 11 22 33 44 Process finished with exit code 0
gevent遇见它能识别的IO它就执行,但是如果不认识,就切换不了:
# from gevent import monkey;monkey.patch_all() import time import gevent def func(): print('11') time.sleep(2) # gevent.sleep(2) print('33') def fu(): print('22') # gevent.sleep(2) time.sleep(2) print('44') g=gevent.spawn(func) g1=gevent.spawn(fu) gevent.joinall([g,g1]) C:UsershcAppDataLocalProgramsPythonPython36python3.exe C:/s9/day40/40.py 11 33 22 44 Process finished with exit code 0
如何解决这个问题?
请用gevent中的monkeyn中的monkey.patch_all()
from gevent import monkey;monkey.patch_all() import time import gevent def func(): print('11') time.sleep(2) # gevent.sleep(2) print('33') def fu(): print('22') # gevent.sleep(2) time.sleep(2) print('44') g=gevent.spawn(func) g1=gevent.spawn(fu) gevent.joinall([g,g1]) C:UsershcAppDataLocalProgramsPythonPython36python3.exe C:/s9/day40/40.py 11 22 33 44 Process finished with exit code 0
from gevent import monkey;monkey.patch_all() import time import gevent from threading import current_thread def func(): print(current_thread().name)#线程名 print('11') time.sleep(2) # gevent.sleep(2) print('33') def fu(): print('22') # gevent.sleep(2) time.sleep(2) print('44') g=gevent.spawn(func) g1=gevent.spawn(fu) gevent.joinall([g,g1]) C:UsershcAppDataLocalProgramsPythonPython36python3.exe C:/s9/day40/40.py DummyThread-1 11 22 33 44 Process finished with exit code 0
二,效率对比
from gevent import monkey;monkey.patch_all() import time import gevent def func(args): time.sleep(1) print(args) def fun(): for i in range(10): func(i) def fu(): l=[] for i in range(10): l.append(gevent.spawn(func,i)) gevent.joinall(l) start=time.time() fun() print(time.time()-start) start=time.time() fu() print(time.time()-start) C:UsershcAppDataLocalProgramsPythonPython36python3.exe C:/s9/day40/40.py 0 1 2 3 4 5 6 7 8 9 10.008541107177734 0 1 2 3 6 5 4 7 8 9 1.002117395401001 Process finished with exit code 0
爬取网址的效率对比
from gevent import monkey;monkey.patch_all() import gevent import time import requests def func(url): res=requests.get(url) print( url,res.status_code,len(res.text)) url_list=['http://www.sohu.com', 'http://www.baidu.com', 'http://www.qq.com', 'http://www.python.org', 'http://www.cnblogs.com', 'http://www.mi.com', 'http://www.apache.org', 'https://www.taobao.com', 'http://www.360.com', 'http://www.7daysinn.cn/' ] start=time.time() for i in url_list: func(i) print(time.time()-start) def fu(url): res = requests.get(url) print(url,res.status_code,len(res.text)) url_lst =[ 'http://www.sohu.com', 'http://www.baidu.com', 'http://www.qq.com', 'http://www.python.org', 'http://www.cnblogs.com', 'http://www.mi.com', 'http://www.apache.org', 'https://www.taobao.com', 'http://www.360.com', 'http://www.7daysinn.cn/' ] g_lst = [] start = time.time() for url in url_lst: g_lst.append(gevent.spawn(fu,url)) gevent.joinall(g_lst) print(time.time() - start)
C:UsershcAppDataLocalProgramsPythonPython36python3.exe C:/s9/day40/40.py http://www.sohu.com 200 186438 http://www.baidu.com 200 2381 http://www.qq.com 200 247169 http://www.python.org 200 48860 http://www.cnblogs.com 200 40834 http://www.mi.com 200 320204 http://www.apache.org 200 60819 https://www.taobao.com 200 125172 http://www.360.com 200 152637 http://www.7daysinn.cn/ 200 29467 4.937240123748779 http://www.mi.com 200 798 http://www.baidu.com 200 2381 http://www.sohu.com 200 186438 http://www.7daysinn.cn/ 200 29467 https://www.taobao.com 200 125172 http://www.qq.com 200 247173 http://www.360.com 200 152637 http://www.cnblogs.com 200 40834 http://www.apache.org 200 60819 http://www.python.org 200 48860 1.7020213603973389 Process finished with exit code 0