【協程】
1.定義:
纖程 微線程,協程本質只有一個線程在運行
2.功能原理:
通過應用層程序,記錄上下文棧區,實現在程序執行過程中的跳躍,
選擇可以不阻塞的部分執行,從而提高IO的執行效率
3.優點:
1.資源消耗很少
2.無需多線程那樣來回切換的開銷
3.無需進行同步互斥操作
4.IO併發性好
缺點:
1.無法利用計算機的多核資源
2.程序不能夠一個客戶端單獨長時間佔有服務端
4.底層實現原理:
yield–>協程的基本實現關鍵字
sudo pip3 install greenlet
sudo pip3 install gevent
(都是第三方模塊,需要安裝)
import greenlet
greenlet.greenlet()
gr.switch()
import gevent
* 將協程事件封裝爲函數
gevent.spawn(func,argv)
功能:
將事件變爲協程事件並啓動
參數:
func 傳入一個函數變爲協程
argv 給func函數傳參
返回值:
協程對象
gevent.joinall()
功能:回收協程
gevent.sleep(n)
功能:模擬IO阻塞的情況
參數:n表示睡眠時間
from gevent import monkey
monkey.patch_all()
功能:
在導入socket模塊之前使用,修改socket的IO設置行爲
5.示例:
from greenlet import greenlet
def test1():
print(12)
gr2.switch()
print(34)
gr2.switch()
def test2():
print(56)
gr1.switch()
print(78)
# 生成協程對象
gr1 = greenlet(test1)
gr2 = greenlet(test2)
# 調用協程函數
gr1.switch()
在終端打印:
12
56
34
78
缺點:函數的跳躍需要人爲的去切換
import gevent
def foo():
print('Running in foo')
gevent.sleep(2)
print('switch to foo again')
def bar():
print('Running in bar')
gevent.sleep(3)
print('switch to bar again')
# 將兩個函數設置爲協程,此時協程函數運行
f = gevent.spawn(foo)
g = gevent.spawn(bar)
# 回收協程
gevent.joinall([f,g])
在終端打印:
Running in foo
Running in bar
switch to foo again
switch to bar again
協程服務器:
import gevent
from gevent import monkey
# 需要在socket導入前執行,改變socket的屬性行爲
monkey.patch_all()
from socket import *
# 套接字創建
def server(port):
s = socket()
s.bind(('0.0.0.0',port))
s.listen(5)
while True:
c,addr = s.accept()
print('Connect from',addr)
gevent.spawn(handle,c)
# 處理客戶端請求
def handle(c):
while True:
data = c.recv(1024)
if not data:
break
print('recv:',data)
c.send(b'Receive your message')
c.close()
if __name__ == '__main__':
server(8888)