单线程实现并发——协程,gevent模块

Posted exman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单线程实现并发——协程,gevent模块相关的知识,希望对你有一定的参考价值。

一 并发的本质  

  1 切换

  2 保存状态

二 协程的概念

  协程,又称微线程,纤程。英文名Coroutine。单线程下实现并发,用户从应用程序级别控制单线程下任务的切换,注意一定是遇到I/O才切。

  协程的特点在于是一个线程执行,那和多线程比,协程有何优势?

  最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。

  第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

  因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。

三 gevent模块

  gevent是一个基于协程的Python网络库。

  需要导入猴子补丁。

  方法:

    g1=gevent.spawn(func,):提交任务。   生成g1,是Greenlet类

    gevent.sleep():睡

    gevent.joinall(可迭代对象):阻塞,知道所有选中的任务执行完毕。

    g1.join() 

    g1.value 获取由func函数生成Greenlet类的返回值。

技术分享图片
import gevent
from gevent import monkey;monkey.patch_all()
from threading import current_thread
import time
def foo():
    print(‘%s is running ‘ % current_thread().getName())
    time.sleep(1)
    print(‘%s is done ‘%current_thread().getName())
def bar():
    print(‘%s is running ‘ % current_thread().getName())
    time.sleep(2)
    print(‘%s is done ‘ % current_thread().getName())

g1=gevent.spawn(foo)      
g2=gevent.spawn(bar)
print(‘g1‘,g1)
print(‘g2‘,g2)

# g1.join()
# g2.join()
gevent.joinall([g1,g2])
技术分享图片

  输出:

g2 <Greenlet at 0x26d7aff0898: bar>
DummyThread-1 is running 
DummyThread-2 is running 
DummyThread-1 is done 
DummyThread-2 is done 

以上是关于单线程实现并发——协程,gevent模块的主要内容,如果未能解决你的问题,请参考以下文章

python全栈脱产第37天------进程池与线程池协程gevent模块单线程下实现并发的套接字通信

Python3-gevent模块-单线程下的"并发"-协程

python 并发编程 协程 gevent模块

13.并发编程之协程

并发编程——协程

并发编程之协程