协程
进程是资源分配的最小单位
线程是cpu调度的最小单位
进程和线程在创建的时候都需要消耗时间,还需要管理他们之间的切换
所有人的目的都是实现并发处理事情
使用单线程单进程完成并发处理
def create_num(all_num):
print(“—1—“)
a,b = 0,1
current_num = 0
while current_num < all_num:
print(“—2—“)
ret = yield a
print(“—-ret—-“,ret)
print(“—3—“)
a,b = b , a+b
current_num+=1
print(“—4—“)
pass
def main():
obj = create_num(10)
ret = next(obj)
print(ret)
ret = obj.send(“haha”)
print(ret)
pass
if name == ‘main‘:
main()
============================
import time
def task_1():
while True:
print(“—1—“)
time.sleep(1)
yield
pass
def task_2():
while True:
print(“—2—“)
time.sleep(2)
yield
pass
def main():
t1 = task_1()
t2 = task_2()
while True:<br /> next(t1)<br /> next(t2)<br /> pass
if name == ‘main‘:
main()
==============================
协程是可以用户自己调度的,是一个轻量级线程
单线程内开启协程,如果碰到了io,就会从应用程序这个级别进行切换
所以协程开销很小,属于程序级别的切换,操作系统感知不到,所以协程是真的轻量级
单线程内实现最大的并发效果,最大程度利用cpu
但是协程本质是单线程的,无法利用多核,所以可以考虑一个程序开多个进程,一个进程开多个线程,每个线程开协程
一般协程指单个线程,一旦协程出现了阻塞,就会整个程序阻塞
修改共享的数据不要加锁
=================================
import time
from greenlet import greenlet
def f1():
res = 1
for i in range(10000000):
res +=1
time.sleep(1)
print(res)
g2.switch()
pass
def f2():
res = 1
for i in range(20000000):
res +=2
time.sleep(1)
print(res)
g1.switch() #此时这个函数的结果凝固,切换到另一个地方
pass
start = time.time()
g1 = greenlet(f1)
g2 = greenlet(f2)
g2.switch() #先开始谁
stop = time.time()
print(stop-start) #1.624s
=======================
import time
from greenlet import greenlet
def f1(g2,g1):
res = 1
for i in range(10000000):
res +=1
time.sleep(1)
print(res)
g2.switch(g1,g2)
pass
def f2(g1,g2):
res = 1
for i in range(20000000):
res +=2
time.sleep(1)
print(res)
g1.switch(g2,g1)
pass
def main():
start = time.time()
g1 = greenlet(f1)
g2 = greenlet(f2)
g2.switch(g1,g2)
stop = time.time()
print(stop - start) # 如果不用greenlet是1.624s,如果用就5s多,并没有解决效率的问题
pass
if name == ‘main‘:
main()
—————————————————
因为greenlet没法解决效率问题,所以用gevent,gevent可以以后用来当协程池,是对greenlet的一个封装
如果不打补丁,就要用gevent.sleep(1) #模拟io阻塞,如果不用模拟io阻塞又不打补丁,就是正常执行规律
from gevent import monkey;monkey.patch_all() #打补丁
import gevent,time
def eat(name):
print(“%s eat 1”%name)
#gevent.sleep(1) #模拟io阻塞
time.sleep(1)
print(“%s eat 2” % name)
pass
def play(name):
print(“%s play 1”%name)
#gevent.sleep(1)
time.sleep(2)
print(“%s play 2” % name)
pass
def main():
g1 = gevent.spawn(eat,’xiaoming’)
g2 = gevent.spawn(play,’xiaohong’)
#g1.join()
#g2.join()
gevent.joinall([g1,g2])
print(“main”)
pass
if name == ‘main‘:
main()
from gevent import monkey;monkey.patch_all() #打补丁
import threading
import gevent,time
def eat(name):
print(threading.current_thread().getName())#显示假线程!!!
print(“%s eat 1”%name)
#gevent.sleep(1) #模拟io阻塞
time.sleep(1)
print(“%s eat 2” % name)
pass
def play(name):
print(threading.current_thread().getName())
print(“%s play 1”%name)
#gevent.sleep(1)
time.sleep(2)
print(“%s play 2” % name)
pass
def main():
g1 = gevent.spawn(eat,’xiaoming’)
g2 = gevent.spawn(play,’xiaohong’)
#g1.join()
#g2.join()
gevent.joinall([g1,g2])
print(“main”)
pass
if name == ‘main‘:
main()
================================
from gevent import spawn,joinall,monkey;monkey.patch_all() #打补丁
import time
def task(pid):
time.sleep(0.5)
print(“task %s done”%pid)
pass
同步
def sync():
for i in range(10):
task(i)
pass
异步
def asynch():
g_1 = [spawn(task,i) for i in range(10)]
joinall(g_1)
print(‘done’)
pass
def main():
#sync() #按流程去做
asynch() #使用协程创建假线程最快速度完成
pass
if name == ‘main‘:
main()
=======================================
