協程greenlet、gevent

greenlet
爲了更好使用協程來完成多任務,python中greenlet模塊對其封裝,從而使得切換任務變得更加簡單
安裝方式python

pip3 install greenlet

示例代碼:網絡

from greenlet import greenlet
import time

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

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

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

# 切換到gr1中運行
gr1.swith() 


gevent
greenlet已經實現了協程,可是這個工人切換,是否是以爲太麻煩了,不要着急,python還有一個比greenlet更強大的而且可以自動切換任務的模塊`gevent`
其原理是當一個greentlet遇到IO(指的是input ouput輸入輸出,好比網絡、文件操做等)操做時,好比訪問網絡,就自動切換到其餘的greenlet,等到IO完成,再適當的時候切換回來繼續執行。dom

因爲IO操做很是耗時,常常使程序處於等待狀態,有了gevent咱們自動切換協程,就保證總有greenlet在運行,而不是等待IOspa

安裝code

pip3 install gevent 

1.gevent的使用協程

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()

運行結果 blog

F:\python3.6\python.exe D:/pythonProjects/pynetwork/coroutine/gevent_demo.py
<Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 0
<Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 1
<Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 2
<Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 3
<Greenlet "Greenlet-0" at 0x22ef10f5c48: f(5)> 4
<Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 0
<Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 1
<Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 2
<Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 3
<Greenlet "Greenlet-1" at 0x22ef12dc048: f(5)> 4
<Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 0
<Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 1
<Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 2
<Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 3
<Greenlet "Greenlet-2" at 0x22ef12dc148: f(5)> 4

Process finished with exit code 0

 

gevent切換執行ip

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()

運行結果 get

F:\python3.6\python.exe D:/pythonProjects/pynetwork/coroutine/gevent_demo.py
<Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 0
<Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 0
<Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 0
<Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 1
<Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 1
<Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 1
<Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 2
<Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 2
<Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 2
<Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 3
<Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 3
<Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 3
<Greenlet "Greenlet-0" at 0x2c45e304c48: f(5)> 4
<Greenlet "Greenlet-1" at 0x2c45e4cc048: f(5)> 4
<Greenlet "Greenlet-2" at 0x2c45e4cc148: f(5)> 4

Process finished with exit code 0

 

3. 給程序打補丁input

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")
])

運行結果

F:\python3.6\python.exe D:/pythonProjects/pynetwork/coroutine/gevent_test.py
work1 0
work2 0
work2 1
work1 1
work1 2
work1 3
work2 2
work1 4
work1 5
work2 3
work1 6
work1 7
work2 4
work2 5
work1 8
work1 9
work2 6
work2 7
work2 8
work2 9

Process finished with exit code 0
相關文章
相關標籤/搜索