• python并发编程之协程


     

    python并发编程之协程

     

    1、协程:
    单线程实现并发
    在应用程序里控制多个任务的切换+保存状态
    优点:
    应用程序级别速度要远远高于操作系统的切换
    缺点:
    多个任务一旦有一个阻塞没有切,整个线程都阻塞在原地
    该线程内的其他的任务都不能执行了

     

    一旦引入协程,就需要检测单线程下所有的IO行为,
    实现遇到IO就切换,少一个都不行,以为一旦一个任务阻塞了,整个线程就阻塞了,
    其他的任务即便是可以计算,但是也无法运行了

     

    2、协程序的目的:
    想要在单线程下实现并发
    并发指的是多个任务看起来是同时运行的
    并发=切换+保存状态

     

    #串行执行
    # import time
    #
    # def func1():
    #     for i in range(10000000):
    #         i+1
    #
    # def func2():
    #     for i in range(10000000):
    #         i+1
    #
    # start = time.time()
    # func1()
    # func2()
    # stop = time.time()
    # print(stop - start)

     

    #基于yield并发执行
    # import time
    # def func1():
    #     while True:
    #         print('func1')
    #         yield
    #
    # def func2():
    #     g=func1()
    #     for i in range(10000000):
    #         print('func2')
    #         i+1
    #         time.sleep(3)
    #         next(g)
    #
    #
    # start=time.time()
    # func2()
    # stop=time.time()
    # print(stop-start)

     对于单线程下,我们不可避免程序中出现io操作,但如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到io阻塞时就切换到另外一个任务去计算,这样就保证了该线程能够最大限度地处于就绪态,即随时都可以被cpu执行的状态,相当于我们在用户程序级别将自己的io操作最大限度地隐藏起来,从而可以迷惑操作系统,让其看到:该线程好像是一直在计算,io比较少,从而更多的将cpu的执行权限分配给我们的线程。

     协程的本质就是在单线程下,由用户自己控制一个任务遇到io阻塞了就切换另外一个任务去执行,以此来提升效率。为了实现它,我们需要找寻一种可以同时满足以下条件的解决方案:

     

    #1. 可以控制多个任务之间的切换,切换之前将任务的状态保存下来,以便重新运行时,可以基于暂停的位置继续执行。
    
    #2. 作为1的补充:可以检测io操作,在遇到io操作的情况下才发生切换

     

    #pip3 install gevent
    # from gevent import monkey,spawn;monkey.patch_all()
    # import time
    #
    # def eat(name):
    #     print('%s eat 1' %name)
    #     time.sleep(3)
    #     print('%s eat 2' %name)
    #
    # def play(name):
    #     print('%s play 1' %name)
    #     time.sleep(1)
    #     print('%s play 2' %name)
    #
    # start=time.time()
    # g1=spawn(eat,'egon')
    # g2=spawn(play,'zmy')
    #
    # g1.join()
    # g2.join()
    # print(time.time() - start)
    # print(g1)
    # print(g2)
    
    
    
    
    
    
    
    
    from gevent import monkey,spawn;monkey.patch_all()
    from threading import current_thread
    import time
    
    def eat():
        print('%s eat 1' %current_thread().name)
        time.sleep(3)
        print('%s eat 2' %current_thread().name)
    
    def play():
        print('%s play 1' %current_thread().name)
        time.sleep(1)
        print('%s play 2' %current_thread().name)
    
    g1=spawn(eat,)
    g2=spawn(play,)
    
    print(current_thread().name)
    g1.join()
    g2.join()

     

  • 相关阅读:
    什么是linux的ftp
    linux安装ftp组件
    菜鸟之linux问题之图形界面和dos界面的登录问题
    linux第一面
    vmware下linux系统的安装过程
    vmware的安装
    装饰器的邪门歪道
    关于任务脚本里面用异步
    写类装饰器的2个小问题
    VUE 与其他常见前端框架对比
  • 原文地址:https://www.cnblogs.com/hanbowen/p/9325701.html
Copyright © 2020-2023  润新知