zoukankan      html  css  js  c++  java
  • python_并发编程——协程

    1.协程

      1.本质上是一个线程。

      2.能偶在多个任务之间切换来节省一下IO时间。

      3.协程中任务之间的切换也消耗时间,但开销要远远小于进程和线程之间的切换。

    真正的协程模块就是使用greenlet来完成多个任务之间的切换。

    from greenlet import greenlet
    
    
    def eat():
        print('eating start')
        g2.switch()  # 切换到g2对象的函数中接着执行,并记录下来当前位置
        print('eating end')
        g2.switch()  # 切换到g2对象的函数中接着执行,并记录下当前位置
    
    
    def play():
        print('playing start')
        g1.switch()  # 切换到g1对象的函数中接着执行,并记录下当前位置
        print('playing end')
    
    
    g1 = greenlet(eat)  # 创建对象并将函数注册到对象中
    g2 = greenlet(play)  # 创建对象并将函数注册到对象中
    g1.switch()  # 切换到g1对象的函数中

    结果:

    2.协程模块

    import gevent
    
    
    def eat():
        print('eating start')
        gevent.sleep(1)  # gevent感知不到time.sleep,这里暂停要用gevent.sleep
        print('eating end')
    
    
    def play():
        print('playing start')
        gevent.sleep(1)
        print('playing end')
    
    
    g1 = gevent.spawn(eat)  # 创建一个协程对象g1,spam括号内第一个参数是函数名,后面可以有多个参数,都是传递给函数的
    g2 = gevent.spawn(play)
    g1.join()  # 等待g1结束
    g2.join()  
    # 这里的join可以换城:geven.joinall([g1,g2]),括号内是一个可迭代对象,可以同时等待g1和g2结束。

    结果:  两个函数同时执行。

     上面代码中如果想用time.sleep或其他阻塞也可以,但是需要如下操作:

    from gevent import monkey  #导入gevent中的monkey模块
    import gevent
    import time
    monkey.patch_all()  # 执行monkey模块中的patch_all方法,就可以使gevent模块识别到time.sleep
    
    
    def eat():
        print('eating start')
        time.sleep(1)
        print('eating end')
    
    
    def play():
        print('playing start')
        time.sleep(1)
        print('playing end')
    
    
    g1 = gevent.spawn(eat)  # 创建一个协程对象g1,spam括号内第一个参数是函数名,后面可以有多个参数,都是传递给函数的
    g2 = gevent.spawn(play)
    g1.join()  # 等待g1结束
    g2.join()

    结果:

     接收返回值:

    from gevent import monkey  #导入gevent中的monkey模块
    import gevent
    import time
    monkey.patch_all()  # 执行monkey模块中的patch_all方法,就可以使gevent模块识别到time.sleep
    
    
    def eat():
        print('eating start')
        time.sleep(1)
        print('eating end')
        return 'wdc'
    
    
    def play():
        print('playing start')
        time.sleep(1)
        print('playing end')
        return 'yhf'
    
    
    g1 = gevent.spawn(eat)  # 创建一个协程对象g1,spam括号内第一个参数是函数名,后面可以有多个参数,都是传递给函数的
    g2 = gevent.spawn(play)
    g2.join()  # 等待g1结束
    g2.join()
    name1 = g1.value  # 接收函数的返回值,需要放在join的后面
    name2 = g2.value
    print(name1, name2)

    结果:  成功打印返回值。

  • 相关阅读:
    精益产品探索
    vue 之 pdf预览
    arcgis js 之 渔网工具(调用地图服务)
    arcgis js之卷帘工具
    arcgis js之调用wms服务
    vue-cli3 本地数据模拟后台接口
    cmd设置电脑自动关机
    Arcgis js之web墨卡托(3857)转经纬度坐标(4326)
    arcgis js之地图分屏同步
    arcgis之gp服务发布
  • 原文地址:https://www.cnblogs.com/wangdianchao/p/12153258.html
Copyright © 2011-2022 走看看