协程

丶灬走出姿态 提交于 2019-11-28 11:17:41

一.协程认识

协程:单线程下的并发,又称为微线程,纤程。一句话说明什么是协程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。

  协程是基于单线程实现并发,即只用一个主线程(cpu只用一个),为实现并发,先认识并发本质(切换+保存状态)

  cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它

  协程本质上就是一个线程,以前线程任务的切换是由操作系统控制的,遇到I/O自动切换,现在我们用协程的目的就是较少操作系统切换的开销

知识点:

1.协程是基于单线程来实现并发
2.协程的三种状态(和进程相同):
    运行、阻塞、就绪3.python的线程属于内核级别,即由操作系统控制调度(如单线程遇到IO或执行时间过长就会交出cpu执行权限,切换其他线程运行)

yield本身就是一种在单线程下可以保存任务运行状态的方法:

import time
def fun1():
    for i in range(10):
        print(f"第{i}次")
        time.sleep(1)
        yield
def fun2():
    g = fun1()
    for k in range(10):
        next(g)             #第一次next,执行到yield结束,再次yield,继续yield下面的代码
fun1()
fun2()

#打印结果:
第0次
第1次
第2次
第3次
第4次
第5次
第6次
第7次
第8次
第9次
通过yield实现任务切换+保存现场
# 计算密集型:串行与协程的效率对比
import time
def task1():
    res = 1
    for i in range(1,100000):
        res += i


def task2():
    res = 1
    for i in range(1,100000):
        res -= i

start_time = time.time()
task1()
task2()
print(time.time()-start_time)


import time


def task1():
    res = 1
    for i in range(1, 100000):
        res += i
        yield res


def task2():
    g = task1()
    res = 1
    for i in range(1, 100000):
        res -= i
        next(g)


start_time = time.time()
task2()
print(time.time() - start_time)


#打印结果(可以看到:串行比协程更效率)
0.009972810745239258
0.018949270248413086
计算密集型 协程和串行的对比(串行效率更高)

但是yield不能检测IO

import time
def fun1():
    while True:
        print("func1")
        yield
def fun2():
    g = fun1()
    for i in range(100000):
        next(g)
        time.sleep(3)
        print("func2")
start_time = time.time()
fun2()
print(time.time() - start_time)
yield不能检测IO,这里用time.sleep()模仿阻塞

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!