多任务之协程浅谈

一、协程(Coroutine)

  1、认识协程

    a>协程,又称为微线程、纤程

    b>协程是Python中另外一种实现多任务的方式,比线程占用更小的执行单位

    c>最通俗的理解:就是一个可以暂停的函数,可以挂起的函数

    d>通过yield生成器可以实现协程

  2、协程和线程的差异

    线程包含在进程中, 协程包含在线程中,一个线程可以包含多个协程,协程的切换开销比线程更小,协程在切换时,不需要保存和恢复线程的状态并发量更高

  3、使用yield生成器实现协程

二、协程-greenlet

  1、greenlet介绍:是Python中的一个模块,是对yield生成器的封装,可更简便实现协程

   2、安装方式及使用

    安装greenlet模块

    sudo pip3 install greenlet

    好比 sudo apt-get install packagename

      -pip3:安装Python3中的模块Linux命令

      -pip:  安装Python2中模块Linux命令

    -使用

    import greenlet

    创建greenlet对象

     g1 = greenlet.greenlet(task):task:要执行的函数名

     g1.switch():执行greenlet

    实例:有两个任务,一个不断打印A,一个不断打印B,通过greenlet实现多任务协程

    参考代码如下:

           

             

五、协程-gevent

  1、使用greenlet的不足:

    1、有多个任务的情况下,人工切换协程非常麻烦

    2、在耗时操作的时候切换协程,耗时操作有很多种

  2、gevent使用原理:

    1、gevent是对greenlet再一次封装

    2、原理是当一个greenlet遇到O(指的是I/O输入输出操作,比如网络、文件访问等)操作时,就自动切换到其他的greenlet,等到O操作完成,再在适当的时候切换回来继续执行。

    3、由于IO操作非常耗时,经常使程序出于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO

  3、gevent的使用

    1、安装gevent模块

      sudo pip3 install gevent

    2、使用

      import gevent

      g1 = gevent.spawn(task)  创建gevent对象,task是任务函数名

      g1.join() 执行gevent对象

    使用gevent实现多任务参考代码:

          

          

  4、gevent写法的优化

    a>简化写法:

      通过一行代码执行所有的协程

      gevent.joinall([gevent.spawn(task1, 3),gevent.spawn(task2, 3)])

     b>给gevent打补丁

      from gevent import monkey

      monkey.patch_all() 打补丁

      参考代码如下:

            

            

六、进程、线程、协程的区别

  进程是操作系统资源分配的单位

  线程是CPU调度的单位

  进程切换需要的资源最大,效率低

  线程切换需要的资源一般,效率一般 (当然在不考虑GIL情况下)

    协程切换需要的资源最小,效率高

  多任务进程、多线程根据CPU核数不一样可能是并行的,但是协程是在一个线程中,所以是并发     一般开发中:使用多进程(一般是CPU的核数)+ 多协程

 

 

 

 

posted @ 2019-02-24 20:50  宠辱不惊666  阅读(326)  评论(0编辑  收藏  举报