zoukankan      html  css  js  c++  java
  • 协程

    协程

    1,定义:

    • 协程:是单线程下的并发,又称微线程,纤程
    • 协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的
    • python的线程属于内核级别的,即由操作系统控制调度,如果单线程遇到IO阻塞或者长时间CPU就会且走,执行其他程序
    • 单线程开启协程,一旦遇到IO阻塞,就会从应用程序级别控制切换,提升效率

    2,优缺点

    • 对比操作系统控制线程之间的切换,协程的区别
      • 优点:
        • 协程的切换开销更小,属于程序级别的切换,操作系统不会操作切换,因此更轻量级
        • 单线程就可以实现并发效果,最大限度的利用CPU
      • 缺点:
        • 协程的本质是单线程,无法利用多核,可以使一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程
    • 总结:
      • 必须在只有一个单线程里实现并发
      • 修改共享数据不需要加锁
      • 用户程序里自己保存多个控制流的上下文栈

    greenlet实现协程

    • greenlet 模块:实现协程任务的切换,属于第三方模块

    • pip install greenlet

    • 单纯的切换,在没有IO阻塞情况下或者没有重复开辟内存空间的操作,不建议使用greenlet模块,会降低程序的执行速度

    • greenlet只是提供了一种比generator更加便捷的切换方式,当切到一个任务执行时如果遇到IO,那就原地阻塞,仍然没有解决遇到IO自动切换来提升效率的问题

    • from greenlet import greenlet
      import time
      def eat(name):
          print('%s eat 1' %name)  # 2
          g2.switch('taibai')  # 3,只需在第一次时传入参数,即可
          time.sleep(3)
          print('%s eat 2' %name)  # 6
          g2.switch()  # 7
      
      def play(name):
          print('%s play 1' %name)  # 4
          g1.switch()  # 5
          print('%s play 2' %name)  # 8
      
      g1=greenlet(eat)
      g2=greenlet(play)
      
      g1.switch('taibai')  # 1 切换到eat任务,
      
      ########################
      taibai eat 1
      taibai play 1
      taibai eat 2
      taibai play 2
      

    Gevent-协程

    • Gevent是一个第三方库,可以轻松的通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

    • 要用gevent,需要将from gevent import monkey;monkey.patch_all()放到文件的开头,就可以识别下面所有的阻塞

    • monkey可以识别time模块的sleep

    • from gevent import monkey;monkey.patch_all() #必须写在最上面,这句话后面的所有阻塞全部能够识别了
      
      import gevent  #直接导入即可
      import time
      def eat():
          #print()  
          print('eat food 1')
          time.sleep(2)  #加上mokey就能够识别到time模块的sleep了
          print('eat food 2')
      
      def play():
          print('play 1')
          time.sleep(1)  #来回切换,直到一个I/O的时间结束,这里都是我们个gevent做得,不再是控制不了的操作系统了。
          print('play 2')
      
      g1=gevent.spawn(eat)
      g2=gevent.spawn(play)
      gevent.joinall([g1,g2])
      print('主')
      #################################
      eat food 1
      play 1
      play 2
      eat food 2
      主
      
    希望你眼眸有星辰,心中有山海,从此以梦为马,不负韶华
  • 相关阅读:
    多表联合查询,利用 concat 模糊搜索
    order by 中利用 case when 排序
    Quartz.NET 3.0.7 + MySql 动态调度作业+动态切换版本+多作业引用同一程序集不同版本+持久化+集群(一)
    ASP.NET Core 2.2 基础知识(十八) 托管和部署 概述
    ASP.NET Core 2.2 基础知识(十七) SignalR 一个极其简陋的聊天室
    ASP.NET Core 2.2 基础知识(十六) SignalR 概述
    ASP.NET Core 2.2 基础知识(十五) Swagger
    ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)
    linux磁盘管理 磁盘查看操作
    linux磁盘管理 文件挂载
  • 原文地址:https://www.cnblogs.com/daviddd/p/12034450.html
Copyright © 2011-2022 走看看