协程

单线程并发:切换(任务I/O阻塞,该任务计算时间过长或有一个更高的优先级取代)+保存状态

        对于第二种,可用生成器yield,next,send或greenlet来实现并发(greenlet切换比yield方便),并不能提高效率。

        对于第一种,用gevent模块,实现I/O切换,提高效率。

协程(微线程):单线程下的并发,用户(应用程序)级别的调度。

                                                 (Python的线程是内核级别的,操作系统级别的调度)

协程的特点:

  1. 必须在只有一个单线程里实现并发
  2. 修改共享数据不需加锁
  3. 用户程序里自己保存多个控制流的上下文栈
  4. 附加:一个协程遇到IO操作自动切换到其它协程。

程序:

# 用generator的send,yield来实现任务的切换
# yield不能实现I/O的切换, 不能提高速率。
def read():
    i = 0
    while True:
        print("haha")
        x = yield
        print(x)


def write():
    g = read()
    next(g)
    for i in range(10):
        g.send(i)  # 切换,发送信息


write()


# pip3 install greenlet 安装
# greenletgreenlet只是提供了一种比generator更加便捷的切换方式,当切到一个任务
# 执行时如果遇到io,那就原地阻塞,仍然是没有解决遇到IO自动切换来提升效率的问题。
from greenlet import greenlet  # 调用
import time


def eat(name):
    print("%s eat1" % name)
    time.sleep(5)  # 不能自动识别并进行I/O切换
    g2.switch("haha")
    print("%s eat2" % name)
    g2.switch()
    pass


def play(name):
    print("%s play1" % name)
    g1.switch()  # 切换到g1
    print("%s play2" % name)
    pass


g1 = greenlet(eat)   # 创建greenlet的对象
g2 = greenlet(play)

g1.switch("alex")  # 给g1发信息,并切换到g1


# pip3 install gevent 模块
# 是异步提交任务
# 遇到IO阻塞时会自动切换任务
from gevent import monkey
monkey.patch_all()
# 实际中可能会遇gevent无法识别的阻塞(如gevent.sleep换为time.sleep),
# 所以应直接将下面的代码打个补丁,用上两行代码可以实现.
import gevent  # 调用
import time


def haha(name):
    print("%s haha1" % name)
    gevent.sleep(3)
    print("%s haha2" % name)


def kuku(name):
    print("%s kuku1" % name)
    time.sleep(5)
    print("%s kuku2" % name)
    return "kuku"


start_time = time.time()
g1 = gevent.spawn(haha, "lulu")  # 创建gevent的对象,可以传参数 2,x = 1
g2 = gevent.spawn(kuku, "lulu")

# g1.join()
# g2.join()
gevent.joinall([g1, g2])  # 等待列表中的协程都执行完毕。
# 要是不加的话,主线程执行完毕,其下的协程也会立即结束
print("主")
print(time.time() - start_time)  # 耗时5.04s,实现了I/O口的自动切换

result1 = g1.value  # 获取相应函数的返回值
result2 = g2.value
print(result1, result2)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值