1. 程式人生 > 程式設計 >Python greenlet和gevent使用程式碼示例解析

Python greenlet和gevent使用程式碼示例解析

greenlet示例

greenlet微執行緒,允許線上程中手動切換

示例1,執行緒切換

from greenlet import greenlet

def test1(x,y):
  z = gr2.switch(x+y)
  print(z)

def test2(u):
  print(u)
  gr1.switch(42)

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch("hello",'world')

gr1和gr2是兩個greenlet執行緒,使用gr1.switch(..)啟動gr1,gr1執行test1,切換到gr2,gr2執行test2列印helloworld,然後切換回gr1,z獲取

到返回值42,並列印.

執行順序為:

gr1.switch("hello",'world') -> test1('hello','world')->

gr2.switch('helloword')->test2('helloworld')->print('helloworld')

->gr1.switch(42)->z=42->print(42)

列印結果:

helloworld
42

示例2

from greenlet import greenlet

def eat(name):
  print('%s eat 1' %name)
  g2.switch('egon')
  print('%s eat 2' %name)
  g2.switch()
def play(name):
  print('%s play 1' %name)
  g1.switch()
  print('%s play 2' %name)

g1=greenlet(eat)
g2=greenlet(play)

g1.switch('egon')#可以在第一次switch時傳入引數,以後都不需要

g1.switch('egon')#可以在第一次switch時傳入引數,以後都不需要

gevent

gevent基於greenlet,遇到IO操作自動切換,IO操作比如網路請求,或使用 gevent.sleep(0)強制切換.

示例1

import gevent

def func1():
  print("start func1")
  gevent.sleep(1)
  print("end func1")

def func2():
   print("start func2")
  gevent.sleep(1)
  print("end func2")

gevent.joinall(
  [
    gevent.spawn(func1),gevent.spawn(func2)
  ]
)

執行結果:

start func1
start func2
end func1
end func2
``

示例2: gevent使用monkey對所有系統自帶的IO操作打patch

```python
from gevent import monkey;monkey.patch_all()

import gevent
import time
def eat():
  print('eat food 1')
  time.sleep(2) # 會自動的跳轉到play
  print('eat food 2')

def play():
  print('play 1')
  time.sleep(1) # 會自動的跳轉到eat
  print('play 2')

g1=gevent.spawn(eat)
g2=gevent.spawn(play)
gevent.joinall([g1,g2])
print('end')

執行結果

eat food 1
play 1
play 2
eat food 2
end

示例3,傳送請求

from gevent import monkey; monkey.patch_all()
import gevent
import requests

def f(url):
  print('GET: %s' % url)
  resp = requests.get(url)
  data = resp.text
  print('%d bytes received from %s.' % (len(data),url))

gevent.joinall([
    gevent.spawn(f,'https://www.python.org/'),gevent.spawn(f,'https://www.yahoo.com/'),'https://github.com/'),])

示例4:使用gevent的socket替代系統的socket

import gevent
from gevent import socket

urls = ['www.baidu.com','www.163.com','www.qq.com']
jobs = [gevent.spawn(socket.gethostbyname,url) for url in urls]
gevent.joinall(jobs,timeout=2)

print([job.value for job in jobs])
或使用patch_socket()
from gevent import monkey; monkey.patch_socket()
import gevent

def f(n):
  for i in range(n):
    print(gevent.getcurrent(),i)
    gevent.sleep(0) # 不加的話不會交替執行
g1 = gevent.spawn(f,5)
g2 = gevent.spawn(f,5)
g3 = gevent.spawn(f,5)
g1.join()
g2.join()
g3.join()

示例5:佇列中使用gevent.sleet(0)強制切換到其他執行緒

import gevent
from gevent.queue import Queue


def func():
  for i in range(10):
    print("int the func")
    q.put(f"test{i}")
    gevent.sleep(0)

def func2():
  for i in range(10):
    print("int the func2")
    res = q.get()
    print("--->",res)

q = Queue()
gevent.joinall(
  [
    gevent.spawn(func2),gevent.spawn(func),]
)

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。