python---协程

1.协程

协程与子例程一样,协程(coroutine)也是一种程序组件。相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛。协程源自 Simula 和 Modula-2 语言,但也有其他语言支持。协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用。
一个程序可以包含多个协程,可以对比与一个进程包含多个线程,因而下面我们来比较协程和线程。我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。

2.yield实现协程

import threading
import time
def producer(c):
    c.__next__()
    n = 0
    while n < 5:
        n += 1
        print("[生产者]生产数据: %s" %(n))
        res = c.send(n)
        print("[消费者的返回值为:%s" %(res))

def consumer():
    r = 'a'
    while True:
        # yield r   ====>  r如何获取? print(c.__next__())
        # n =  yield r   ==> c.send("任务1")   ===> n = "任务1"
        n =  yield r
        if not n:
            return
        print("[消费者]运行%s....." %(n))
        time.sleep(1)
        r = '200 OK'

# # 函数中有yield, 返回值为生成器;
# c = consumer()
# #
# print(c.__next__())
# print(c.send("任务1"))


if __name__ == '__main__':
    # 查看当
    print(threading.active_count())
    c = consumer()
    producer(c)
    print(threading.active_count())

在这里插入图片描述

3.gevent协程实现

import time
from gevent import  monkey
monkey.patch_all()

import  gevent
def job(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        time.sleep(1)

def main1():
    # 创建三个协程, 并让该协程执行job任务
    # 假设多协程执行的任务, 没有IO操作或者等待, 那么协程间是依次运行, 而不是交替运行;
    # 假设多协程执行的任务, IO操作或者等待, 那么协程间是交替运行;
    g1 = gevent.spawn(job, 2)
    g2 = gevent.spawn(job, 3)
    g3 = gevent.spawn(job, 2)
    # 等待所有的协程执行结束, 再执行主程序;
    # g1.join()
    # g2.join()
    # g3.join()
    gevent.joinall([g1, g2, g3])
    print("任务执行结束.....")

main1()

在这里插入图片描述

4协程案例

import time
from urllib.request import urlopen
from concurrent.futures import  ThreadPoolExecutor
import gevent

# 1. 打补丁
from gevent import  monkey
from mytimeit import timeit
monkey.patch_all()

# 2. 确定多协程执行的任务内容;
def load_url(url):
    # print("正在处理%s...." %(url))
    with urlopen(url) as conn:
        data = conn.read()
        print("%s网页字节数为%s" %(url, len(data)))

URLS = ['http://httpbin.org', 'http://example.com/']*100

@timeit
def gevent_main():
    gevents = [gevent.spawn(load_url, url) for url in URLS]
    gevent.joinall(gevents)


@timeit
def thread_main():
    with  ThreadPoolExecutor(max_workers=100) as f:
        f.map(load_url, URLS)

if __name__ == '__main__':
    gevent_main()
    thread_main()

4.协程案例

import time
from urllib.request import urlopen
from concurrent.futures import  ThreadPoolExecutor
import gevent

# 1. 打补丁
from gevent import  monkey
from mytimeit import timeit
monkey.patch_all()

# 2. 确定多协程执行的任务内容;
def load_url(url):
    # print("正在处理%s...." %(url))
    with urlopen(url) as conn:
        data = conn.read()
        print("%s网页字节数为%s" %(url, len(data)))

URLS = ['http://httpbin.org', 'http://example.com/']*100

@timeit
def gevent_main():
    gevents = [gevent.spawn(load_url, url) for url in URLS]
    gevent.joinall(gevents)


@timeit
def thread_main():
    with  ThreadPoolExecutor(max_workers=100) as f:
        f.map(load_url, URLS)

if __name__ == '__main__':
    gevent_main()
    thread_main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值