python并发编程之协程

 

python并发编程之协程

 

1、协程:
单线程实现并发
在应用程序里控制多个任务的切换+保存状态
优点:
应用程序级别速度要远远高于操作系统的切换
缺点:
多个任务一旦有一个阻塞没有切,整个线程都阻塞在原地
该线程内的其他的任务都不能执行了

 

一旦引入协程,就需要检测单线程下所有的IO行为,
实现遇到IO就切换,少一个都不行,以为一旦一个任务阻塞了,整个线程就阻塞了,
其他的任务即便是可以计算,但是也无法运行了

 

2、协程序的目的:
想要在单线程下实现并发
并发指的是多个任务看起来是同时运行的
并发=切换+保存状态

 

#串行执行
# import time
#
# def func1():
#     for i in range(10000000):
#         i+1
#
# def func2():
#     for i in range(10000000):
#         i+1
#
# start = time.time()
# func1()
# func2()
# stop = time.time()
# print(stop - start)

 

#基于yield并发执行
# import time
# def func1():
#     while True:
#         print('func1')
#         yield
#
# def func2():
#     g=func1()
#     for i in range(10000000):
#         print('func2')
#         i+1
#         time.sleep(3)
#         next(g)
#
#
# start=time.time()
# func2()
# stop=time.time()
# print(stop-start)

 对于单线程下,我们不可避免程序中出现io操作,但如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到io阻塞时就切换到另外一个任务去计算,这样就保证了该线程能够最大限度地处于就绪态,即随时都可以被cpu执行的状态,相当于我们在用户程序级别将自己的io操作最大限度地隐藏起来,从而可以迷惑操作系统,让其看到:该线程好像是一直在计算,io比较少,从而更多的将cpu的执行权限分配给我们的线程。

 协程的本质就是在单线程下,由用户自己控制一个任务遇到io阻塞了就切换另外一个任务去执行,以此来提升效率。为了实现它,我们需要找寻一种可以同时满足以下条件的解决方案:

 

#1. 可以控制多个任务之间的切换,切换之前将任务的状态保存下来,以便重新运行时,可以基于暂停的位置继续执行。

#2. 作为1的补充:可以检测io操作,在遇到io操作的情况下才发生切换

 

#pip3 install gevent
# from gevent import monkey,spawn;monkey.patch_all()
# import time
#
# def eat(name):
#     print('%s eat 1' %name)
#     time.sleep(3)
#     print('%s eat 2' %name)
#
# def play(name):
#     print('%s play 1' %name)
#     time.sleep(1)
#     print('%s play 2' %name)
#
# start=time.time()
# g1=spawn(eat,'egon')
# g2=spawn(play,'zmy')
#
# g1.join()
# g2.join()
# print(time.time() - start)
# print(g1)
# print(g2)








from gevent import monkey,spawn;monkey.patch_all()
from threading import current_thread
import time

def eat():
    print('%s eat 1' %current_thread().name)
    time.sleep(3)
    print('%s eat 2' %current_thread().name)

def play():
    print('%s play 1' %current_thread().name)
    time.sleep(1)
    print('%s play 2' %current_thread().name)

g1=spawn(eat,)
g2=spawn(play,)

print(current_thread().name)
g1.join()
g2.join()

 

原文地址:https://www.cnblogs.com/hanbowen/p/9325701.html