python yield 模拟协程实验

发布时间 2023-03-31 19:34:56作者: MrSphere

Pyhton3.10 yield 模拟协程实验

实验原理

协程,单线程解决并发问题
什么是并发? 并发指的是多个任务看起来是同时运行的,并发=切换+保存状态
优点:应用程序级别速度要远远高于操作系统的切换
缺点:线程内其他的任务都不能执行了,一旦引入协程,就需要监测单线程下所有的IO行为,实现遇到IO就切换
并不是所有的程序使用协程就能加大运行效率,只有单线程下多个任务遇到IO切换才能提升效率。

在python 中,在执行任务的时候切换当前正在任务的有一个很像的方法,就是yield

任务:在10**6的范围的数字,偶数生成文件模拟IO操作,奇数打印出来模拟计算操作。

实验1:

# -*- coding: utf-8 -*-
import os.path
import time

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
FILE_DIR = os.path.join(BASE_DIR, 'test')
if not os.path.exists(FILE_DIR):
    os.mkdir(FILE_DIR)


def consumer():
    # 接收数据,处理数据
    while True:
        i = yield
        with open(os.path.join(FILE_DIR, f"{i}.txt"), 'w', encoding='utf-8') as f:
            f.write(str(i))


def producer():
    # 生产数据
    g = consumer()
    next(g)

    for i in range(100000):
        if i % 2:
            g.send(i)
        else:
            print(i)


start = time.time()
producer()
stop = time.time()

print(stop - start)  # 28.668668031692505

# -*- coding: utf-8 -*-
import os.path
import time

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
FILE_DIR = os.path.join(BASE_DIR, 'test')
if not os.path.exists(FILE_DIR):
    os.mkdir(FILE_DIR)


def producer():
    # 生产数据
    for i in range(100000):
        if i % 2:
            with open(os.path.join(FILE_DIR, f"{i}.txt"), 'w', encoding='utf-8') as f:
                f.write(str(i))
        else:
            print(i)


start = time.time()
producer()
stop = time.time()

print(stop - start) # 26.07617688179016

实验结果:在单纯使用yield方法,在同一线程下实现IO密集型任务和计算密集型任务切换,会使得任务执行总体时间增加。