python 多任务-协程(十五-3)

介绍-> 阻塞和非阻塞

阻塞:从调用者的角度出发,如果在调用的时候,被卡住,不能再继续向下运行,需要等待,就说是阻塞

非阻塞:从调用者的角度出发, 如果在调用的时候,没有被卡住,能够继续向下运行,无需等待,就说是非阻塞

三、使用yield完成多任务

       yield特点:

              1.将数据返回出来,

              2.返回数据之后,进行暂停挂起机制

              3.下一次启动时,从哪里暂停,就从哪里开始

def play():
    '''玩游戏'''
    while True:
       print('玩游戏 .....')
       time.sleep(.5)
       yield   # 没有返回值的情况下,起到暂停挂起的效果

def network():
    '''上网'''
    while True:
        print('上网.....')
        time.sleep(.5)
        yield  # 没有返回值的情况下,起到暂停挂起的效果

#通过方法调用
def main():
   p=play()  # 生成器对象,next()就可以调用一次生成器模板
   n=network()
   # next(p)  # 变成了非阻塞状态
   # next(n)
   #它们执行一次,就暂停了!那么就必须使用循环了哦!
   while True:
       next(p) # 变成了非阻塞状态
       next(n)

if __name__=='__main__':
   main()

小结:

   yield完成多任务: 一个进程, 一个线程: 占用的资源最少。 利用的是yield暂停挂起的机制,让程序变成非阻塞的效果,从而达到可以切换任务的目的,进行多任务。

  其实就是一个假的多任务:是单线程 利用的是yield的挂起机制,让程序变成非阻塞状态,以此来切换任务。 类似多线程CPU的切换。

 

四、使用greenlet完成多任务

    greenlet 是对yield进程了封装  它是第三方库 pip install greenlet -i https://pypi.douban.com/simple  可以在Terminal 查看 pip list 回车 如果还是没有,可以重启pycharm哦!

from greenlet import greenlet
import time

def play():
    '''玩游戏'''
    while True:
       print('玩游戏 .....')
       time.sleep(.5)
       #手动切换-network
       gl2.switch()


def network():
    '''上网'''
    while True:
        print('上网.....')
        time.sleep(.5)
        # 手动切换-play
        gl1.switch()


def main():
    gl1.switch() #进行切换,切换到对象的指向部分

if __name__=='__main__':
    #创建greenlet对象,对yield进行了封装
   gl1= greenlet(play) #创建对象,指向了play函数
   gl2= greenlet(network) #创建对象,指向了network函数
   main()

效果同上:忽略

小结:greenlet实现多任务的原理,让程序变成非阻塞,,来回切换任务,达到多任务的效果.

五、使用gevent完成多任务

 第三方库
 greentlet  >yield
 gevent > greenlet
from gevent import  monkey
import time
#打补丁
monkey.patch_all() #只要执行这个代码,程序中的延时操作,就会骗过gevent,让它看成自己的延时

def play():
    '''玩游戏'''
    for i in range(1,6):
       print(f'玩第{i}个游戏')
       time.sleep(.5)

def network():
    '''上网'''
    for i in range(1,6):
        print(f'网冲浪第{i}个')
        time.sleep(.5)  #通过打补丁的方式,骗过gevent,当作正常的延时。


#通过方法调用
def main():
   gv1.join()   #类似于启动
   gv2.join()   #类似于启动

if __name__=='__main__':
    #使用gevent进行任务
    gv1=gevent.spawn(play)
    gv2=gevent.spawn(network)
    main()

说明:无法避免的延迟操作(协程进行任务切换哦) (1) 网络延迟 (2) 文件读写

小结:gevent原理: 单进程,单线程的情况下,让程序一旦碰到延时操作就自动进行任务的切换,变成非阻塞状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值