# 生成器 yield def func1(): print(1) yield print(3) yield def func2(): g = func1() # 生成器函数在被调用时不会当即执行,除非next(g)触发才能够 next(g) # 开始执行func1()函数,可是遇到yield就会中止 print(2) next(g) print(4) func2() # 结果呈现 1 2 3 4
def consumer(): # 消费者模型 while True: n = yield # yield接收g.send()的结果,而后赋值给n print("消费了包子 %s" % n) def producer(): # 生产者模型 g = consumer() # 调用生成器函数,并不会理解执行生成器函数内部的代码(除非next()进行触发) next(g) # 开始执行生成器函数 for i in range(10): print("生产了包子 %s" % i) g.send(i) # send()给生成器函数yield处接收 producer() # 结果呈现 生产了包子 0 消费了包子 0 生产了包子 1 消费了包子 1 生产了包子 2 消费了包子 2 生产了包子 3 消费了包子 3 生产了包子 4 消费了包子 4 生产了包子 5 消费了包子 5 生产了包子 6 消费了包子 6 生产了包子 7 消费了包子 7 生产了包子 8 消费了包子 8 生产了包子 9 消费了包子 9
import time from greenlet import greenlet # 在单线程中切换状态的模块 def eat1(): print("吃鸡腿") g2.switch() # 切换执行eat2 time.sleep(5) # greenlet进行切换时,并不会规避掉IO时间(也就是切换回来时仍是须要等待2秒在执行) print("吃鸡翅") g2.switch() # 切换执行eat2 def eat2(): print("吃饺子") g1.switch() # 切换执行eat1 time.sleep(3) # greenlet进行切换时,并不会规避掉IO时间(也就是切换回来时仍是须要等待2秒在执行) print("白切鸡") g1 = greenlet(eat1) g2 = greenlet(eat2) g1.switch() # 切换执行eat1 # 结果呈现 吃鸡腿 吃饺子 吃鸡翅 白切鸡
#顺序执行 import time def f1(): res=1 for i in range(100000000): res+=i def f2(): res=1 for i in range(100000000): res*=i start=time.time() f1() f2() stop=time.time() print('run time is %s' %(stop-start)) #10.985628366470337 #切换 from greenlet import greenlet import time def f1(): res=1 for i in range(100000000): res+=i g2.switch() def f2(): res=1 for i in range(100000000): res*=i g1.switch() start=time.time() g1=greenlet(f1) g2=greenlet(f2) g1.switch() stop=time.time() print('run time is %s' %(stop-start)) # 52.763017892837524
# gevent 内部封装了greenlet模块 import gevent def eat(name): print('%s eat 1' %name) gevent.sleep(2) # gevent能够在gevevt.sleep()本身认识的IO操做切换 print('%s eat 2' %name) def play(name): print('%s play 1' %name) gevent.sleep(1) print('%s play 2' %name) g1=gevent.spawn(eat,'egon') g2=gevent.spawn(play,name='egon') # g1.join() # g2.join() gevent.joinall([g1,g2]) # 至关于上面的g1.join() g2.join() # 结果呈现 egon eat 1 egon play 1 egon play 2 egon eat 2
import gevent,time def eat(name): print('%s eat 1' %name) time.sleep(2) print('%s eat 2' %name) def play(name): print('%s play 1' %name) time.sleep(1) print('%s play 2' %name) g1=gevent.spawn(eat,'egon') g2=gevent.spawn(play,name='egon') gevent.joinall([g1,g2]) # 结果呈现 egon eat 1 egon eat 2 egon play 1 egon play 2
from gevent import monkey;monkey.patch_all()
必须放到被打补丁者的前面,如time,socket模块以前threading.current_thread().getName()
来查看每一个g1和g2,查看的结果为DummyThread-n,即假线程from gevent import monkey;monkey.patch_all() # 加上这句话,gevent遇到其余模块(time,socket等IO操做)的IO 须要等待时 就会切换协程 from threading import current_thread import gevent,time def func1(): print(current_thread().name) # 打印当前线程名(其实协程并非线程,多个协程是在同一个线程内完成的) print(123) time.sleep(1) print(456) def func2(): print(current_thread().name) print(789) time.sleep(1) print(101112) g1 = gevent.spawn(func1) # 碰见它认识的io会自动切换的模块 g2 = gevent.spawn(func2) # g1.join() # g2.join() gevent.joinall([g1,g2]) # 结果呈现 DummyThread-1 123 DummyThread-2 789 456 101112
from gevent import monkey;monkey.patch_all() import gevent,time def task(args): time.sleep(1) print(args) def sync_fucn(): # 同步 for i in range(10): task(i) def async_func(): # 异步 g_lst = [] for i in range(10): g_lst.append(gevent.spawn(task,i)) # 发起协程任务,传参数 gevent.joinall(g_lst) start = time.time() sync_fucn() print(time.time() - start) start = time.time() async_func() print(time.time() - start) # 结果呈现 0 1 2 3 4 5 6 7 8 9 10.011728048324585 0 1 2 3 4 5 6 7 8 9 1.0025279521942139
# 爬去网页信息的例子 from gevent import monkey;monkey.patch_all() import gevent,requests,time # 协程函数发起10个网页的爬取任务 def get_url(url): res = requests.get(url) print(url,res.status_code,len(res.text)) # 返回爬取网页的信息(requests.get(url).text----获取网页源代码; requests.get(url).status_code----获取网页状态码) 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" ] g_lst = [] start = time.time() for url in url_lst: g = gevent.spawn(get_url,url) g_lst.append(g) gevent.joinall(g_lst) print(time.time() - start) start = time.time() for url in url_lst: get_url(url) print(time.time() - start) # 结果呈现 http://www.baidu.com 200 2381 http://www.sohu.com 200 178923 http://www.qq.com 200 205793 http://www.mi.com 200 312788 http://www.cnblogs.com 200 41063 http://www.apache.org 200 62019 http://www.python.org 200 49235 1.198430061340332 http://www.sohu.com 200 178923 http://www.baidu.com 200 2381 http://www.qq.com 200 205793 http://www.python.org 200 49235 http://www.cnblogs.com 200 41043 http://www.mi.com 200 312788 http://www.apache.org 200 62019 2.1779263019561768
# server import socket sk = socket.socket() sk.bind(("127.0.0.1",8080)) sk.listen() conn,addr = sk.accept() ret = conn.recv(1024).decode("utf-8") print(ret) conn.send(ret.upper().encode("utf-8")) conn.close() sk.close()
# client import socket sk = socket.socket() sk.connect(("127.0.0.1",8080)) sk.send(b"hi") ret = sk.recv(1024).decode("utf-8") print(ret) sk.close()
# server from gevent import monkey;monkey.patch_all() import socket,gevent def talk(conn): while True: ret = conn.recv(1024).decode("utf-8") print(ret) conn.send(ret.upper().encode("utf-8")) conn.close() sk = socket.socket() sk.bind(("127.0.0.1",8080)) sk.listen() while True: conn,addr = sk.accept() gevent.spawn(talk,conn) sk.close()
# client from gevent import monkey;monkey.patch_all() import socket,gevent,time,threading def my_client(): sk = socket.socket() sk.connect(("127.0.0.1",8080)) while True: sk.send(b"hi") ret = sk.recv(1024).decode("utf-8") print(ret) time.sleep(1) sk.close() for i in range(500): threading.Thread(target=my_client).start()
(cpucount + 1 ) * cpucount * 5 * 500并发 == 50000
html
转自:https://www.cnblogs.com/Eva-J/articles/8324673.htmlpython