Python并发编程之协程(greenlet、gevent)

友情链接:

  • Python并发编程之协程【必知必会】

文章目录

    • 一、greenlet
      • 1.1 安装方式
      • 1.2 greenlet的使用
    • 二、gevent
      • 2.1 安装方式
      • 2.2 gevent的使用
      • 2.3 gevent切换执行
      • 2.4 给程序打补丁

一、greenlet

为了更好使用协程来完成多任务,Python中的greenlet模块对其封装,从而使得切换任务变的更加简单。

1.1 安装方式

使用如下命令安装greenlet模块:

sudo pip3 install greenlet

1.2 greenlet的使用

from greenlet import greenlet
import time


def test1():
    while True:
        print("---A--")
        gr2.switch()
        time.sleep(0.5)


def test2():
    while True:
        print("---B--")
        gr1.switch()
        time.sleep(0.5)


gr1 = greenlet(test1)
gr2 = greenlet(test2)

# 切换到gr1中运行
gr1.switch()

Python并发编程之协程(greenlet、gevent)_第1张图片

二、gevent

greenlet已经实现了协程,但是这个还需要人工切换,比较麻烦。Python为了更好的实现协程,还有一个比greenlet更强大的并且能够自动切换任务的模块gevent

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

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

2.1 安装方式

pip3 install gevent

2.2 gevent的使用

gevent.getcurrent():保存该协程的相关信息。

import gevent


def f(n):
    for i in range(n):
        print(gevent.getcurrent(), i)


g1 = gevent.spawn(f, 5)
g2 = gevent.spawn(f, 5)
g3 = gevent.spawn(f, 5)
g1.join()
g2.join()
g3.join()

Python并发编程之协程(greenlet、gevent)_第2张图片
可以看到,3个greenlet是依次运行而不是交替运行。

2.3 gevent切换执行

import gevent


def f(n):
    for i in range(n):
        print(gevent.getcurrent(), i)
        # 用来模拟一个耗时操作,注意不是time模块中的sleep
        gevent.sleep(1)


g1 = gevent.spawn(f, 5)
g2 = gevent.spawn(f, 5)
g3 = gevent.spawn(f, 5)
g1.join()
g2.join()
g3.join()

Python并发编程之协程(greenlet、gevent)_第3张图片

2.4 给程序打补丁

from gevent import monkey
import gevent
import random
import time


def coroutine_work(coroutine_name):
    for i in range(10):
        print(coroutine_name, i)
        time.sleep(random.random())


gevent.joinall([
    gevent.spawn(coroutine_work, "work1"),
    gevent.spawn(coroutine_work, "work2")
])

Python并发编程之协程(greenlet、gevent)_第4张图片

from gevent import monkey
import gevent
import random
import time

# 有耗时操作时需要
monkey.patch_all()  # 将程序中用到的耗时操作的代码,换为gevent中自己实现的模块


def coroutine_work(coroutine_name):
    for i in range(10):
        print(coroutine_name, i)
        time.sleep(random.random())


gevent.joinall([
    gevent.spawn(coroutine_work, "work1"),
    gevent.spawn(coroutine_work, "work2")
])

Python并发编程之协程(greenlet、gevent)_第5张图片

你可能感兴趣的:(Python,python,协程,greenlet,gevent)