协程的实现

协程

协程:又称微线程纤程。英文名Coroutine。那协程到底是个什么东西,通俗的讲就是比线程还要小的线程,所以才叫微线程。

  主要作用:有人要问了,在python中线程是原子操作(意思就是说一句话或者一个动作就能搞定的操作或者计算),怎么还有个叫协程的呢?

  优点:

1、使用高并发、高扩展、低性能的;一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。

2、无需线程的上下文切换开销(乍一看,什么意思呢?我们都知道python实际上是就是单线程,那都是怎么实现高并发操作呢,就是CPU高速的切换,每个任务都干一点,最后看上去是一起完事儿的,肉眼感觉就是多线程、多进程)

  缺点:

    1、无法利用CPU的多核优点,这个好理解,进程里面包含线程,而协程就是细分后的线程,也就是说一个进程里面首先是线程其后才是协程,那肯定是用不了多核了,不过可以多进程配合,使用CPU的密集运算,平时我们用不到。

  2、一般情况下用的比较多的是asyncio或者是gevent这两个技术实现协程,asyncio是python自带的技术,gevent第三方库。

和多线程比,协程有何优势?

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

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

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

代码使用

from gevent import monkey
monkey.patch_all()
# # gevent本身识别不了time.sleep等不属于该模块内的io操作
from gevent import spawn
import time


def ping(name):
    print("%sPing" % name)
    time.sleep(2)
    print("%s Ping" % name)


def pong(name):
    print("%sPong" % name)
    time.sleep(2)
    print("%sPong" % name)


start_time = time.time()
s1 = spawn(ping, "Ashe") # 把任务和参数提交给gevent下面spawn方法
s2 = spawn(pong, "EZreal")
s1.join() # 任务执行的太快,还有有结果节退出了,所以加了一个守护线程
s2.join()
print("主", time.time() - start_time)

# 输出结果
AshePing
EZrealPong
Ashe Ping
EZrealPong
主 2.0077295303344727
原文地址:https://www.cnblogs.com/ruhai/p/10840616.html