zoukankan      html  css  js  c++  java
  • python 并发编程之协程

    一、协程

    协程: 单线程下的并发,又称 微线程。协程是一种用户态的的轻量级线程,即协程是由用户程序自己控制调度的。

    协程的本质就是在单线程下,由用户自己控制一个任务,遇到 io 阻塞就切换另外一个任务去执行,以此来提升效率。

    1、python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出cpu执行权限,切换其他线程运行)

    2、单线程内开启协程,一旦遇到io,就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(!!!非io操作的切换与效率无关)

    对比操作系统控制线程的切换,用户在单线程内控制协程的切换:

    优点:

    • 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级
    • 单线程内就可以实现并发的效果,最大限度地利用cpu

    缺点:

    • 协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程
    • 协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程

    gevent

    import gevent
    import time
    
    def run(name):
        print('%s is running 1 ...' %name)
        gevent.sleep(3)
        print('%s is running 2 ...' %name)
    
    def jump(name):
        print('%s is jumping 1 ...' %name)
        gevent.sleep(4)
        print('%s is jumping 2 ...' %name)
    
    start_time = time.time()
    g1 = gevent.spawn(run, 'fury')
    g2 = gevent.spawn(jump, 'tiger')
    
    g1.join()
    g2.join()
    stop_time = time.time()
    print(stop_time - start_time)
    
    --- 执行结果 ---
    fury is running 1 ...
    tiger is jumping 1 ...
    fury is running 2 ...
    tiger is jumping 2 ...
    4.00600004196167
    

    分析: run() 中 gevent.sleep(3) ,切到 jump() ,jump() 中执行到 gevent.sleep(4) 时候,又切到 run() ,run() 中 gevent.sleep(3) ,3s 还没完,又切回到 jump() ,就这样反复切, 然后 fun() 3s 结束后,执行下面的代码,然后又执行 jump() 中的代码

    最后的执行时间,与 jump() 中 gevent.sleep(4) 的4s 很接近,

    from gevent import monkey;monkey.patch_all()  # 打补丁 将下面涉及到 io 操作的都上标记,这样,不是gevent的io 操作,也可以被  gevent 识别啦
    # 不加上面这句,下面代码执行后遇到io 是不切,而是直接 time.sleep() 睡眠的
    import gevent
    import time
    
    def run(name):
        print('%s is running 1 ...' %name)
        time.sleep(3)
        print('%s is running 2 ...' %name)
    
    def jump(name):
        print('%s is jumping 1 ...' %name)
        time.sleep(4)
        print('%s is jumping 2 ...' %name)
    
    start_time = time.time()
    g1 = gevent.spawn(run, 'fury')
    g2 = gevent.spawn(jump, 'tiger')
    
    g1.join()
    g2.join()
    stop_time = time.time()
    print(stop_time - start_time)
    
  • 相关阅读:
    【乱侃】How do they look them ?
    【softeware】Messy code,some bug of Youdao notebook in EN win7
    【随谈】designing the login page of our project
    【web】Ad in security code, making good use of resource
    SQL数据库内存设置篇
    关系数据库的查询优化策略
    利用SQL未公开的存储过程实现分页
    sql语句总结
    sql中使用cmd命令注销登录用户
    SQLServer 分页存储过程
  • 原文地址:https://www.cnblogs.com/friday69/p/9685781.html
Copyright © 2011-2022 走看看