協程—gevent模塊的使用


gevent:認識一

import time
import gevent

# 帶有io操作的內容寫在函數里,然后提交func函數給gevent
def func():
    print("start func ...")
    gevent.sleep(1)
    print("end func ...")

g1 = gevent.spawn(func)

time.sleep(1.5)

1、程序執行到 g1 = gevent.spawn(func) 這一步之后,並不會執行func協程函數。如果后面沒有了,程序會直接退出。

2、所以需要加個阻塞(io阻塞或其他阻塞),讓程序不能退出,那么程序遇到阻塞就會切換到func協程函數里面執行。那么事實到底是不是呢?

3、這里我是用time.sleep(1.5)阻塞程序的,但是time,sleep(1.5)此時無效,程序等待1.5秒后退出,仍然沒有執行func協程函數。尷尬嘍!因為不認識time為阻塞函數,所以就不會切換到協程函數。那么怎么認識time.sleep()函數呢?就需要導入from gevent import monkey這個啦!

4、協程就是在單線程中,多個任務不停地切換執行。如果線程不阻塞,程序很快運行結束了,那么協程就不會執行的。即使阻塞,也需要讓協程認識才行,這樣才會自動切換到協程函數里面執行。協程認識的阻塞函數就那么幾個,可以查看monkey.patch_all(),主要就是socket的一些阻塞函數。

gevent:認識二

from gevent import monkey
monkey.patch_all()
import time         # 在time之前導入monkey,就認識time阻塞嘍!
import gevent

# 帶有io操作的內容寫在函數里,然后提交func函數給gevent
def func():
    print("start func ...")
    gevent.sleep(1)
    print("end func ...")
  
g1 = gevent.spawn(func)
  
time.sleep(1.5)

一、gevent 如何檢測是否能規避某個模塊的io操作呢?在patch_all之前打印一次,在patch_all之后打印一次,如果兩次的結果不一樣,那么就說明能夠規避io操作。

二、不容易呀,終於執行協程函數了!但是用time.sleep()函數阻塞不好,因為不清楚協程函數到底需要執行多長時間呢?這里有另一個方法,見下面:

gevent:認識三

from gevent import monkey
monkey.patch_all()   # 這兩行是為了改變模塊一些特性,如time模塊,socket模塊,這樣才能識別time.sleep()與sock.accept()與sock.recv()等為阻塞函數,進行切換。
import time
import gevent

def foo(a):
    print("Running in foo", a)
    gevent.sleep(2)
    print("switch to foo again")

def func():
    print("Running in func ...")
    gevent.sleep(3)
    print("switch to func again...")
  
# 將事件函數加入協程,就變成協程函數了
g1 = gevent.spawn(func)
g2 = gevent.spawn(foo, 1)
  
# g1.join()
# g2.join()
gevent.joinall([g1, g2])   # 回收協程,比一個一個回收方便一點 

gevent:協程解決網絡阻塞實例,實現並發

服務端:

from gevent import monkey
monkey.patch_all()
import socket
import gevent

def func(conn):
    while True:
        msg = conn.recv(1024).decode("utf-8")
        MSG = msg.upper()
        conn.send(MSG.encode("utf-8"))

server = socket.socket()           
server.bind(("127.0.0.1", 3120))
server.listen()
 
while True:
    conn, addr = server.accept()
    gevent.spawn(func, conn)

客戶端:

import time
import socket
from threading import Thread

def client():
    client = socket.socket()        
    client.connect(("127.0.0.1", 3120))
	
    while True:
        client.send(b"hello")
        data = client.recv(1024)
        print(data.decode())
        time.sleep(1)
        
for i in range(5):
    Thread(target=client).start()

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM