1、協程
程序:資源機關
線程:執行機關
協程:這個概念完全是程式員自己意淫出來的 根本不存在
協程是單線程下實作并發
我們程式員自己再代碼層面上檢測我們所有的IO操作
一旦遇到IO了 我們在代碼級别完成切換
這樣給CPU的感覺是你這個程式一直在運作 沒有IO
進而提升程式的運作效率
多道技術
切換+儲存狀态
CPU兩種切換
1.程式遇到IO
2.程式長時間占用
TCP服務端
accept
recv
代碼如何做到
切換+儲存狀态
切換
切換不一定是提升效率 也有可能是降低效率
IO切 提升
沒有IO切 降低
儲存狀态
儲存上一次我執行的狀态 下一次來接着上一次的操作繼續往後執行
yield
“”"
2、 驗證切換是否就一定提升效率
import time
# 串行執行計算密集型的任務 1.2372429370880127
def func1():
for i in range(10000000):
i + 1
def func2():
for i in range(10000000):
i + 1
start_time = time.time()
func1()
func2()
print(time.time() - start_time)
切換 + yield 2.1247239112854004
import time
def func1():
while True:
10000000 + 1
yield
def func2():
g = func1() # 先初始化出生成器
for i in range(10000000):
i + 1
next(g)
start_time = time.time()
func2()
print(time.time() - start_time)
2、 gevent子產品(了解)
安裝
pip3 install gevent
from gevent import monkey;monkey.patch_all()
import time
from gevent import spawn
"""
gevent子產品本身無法檢測常見的一些io操作
在使用的時候需要你額外的導入一句話
from gevent import monkey
monkey.patch_all()
又由于上面的兩句話在使用gevent子產品的時候是肯定要導入的
是以還支援簡寫
from gevent import monkey;monkey.patch_all()
"""
def heng():
print('哼')
time.sleep(2)
print('哼')
def ha():
print('哈')
time.sleep(3)
print('哈')
def heiheihei():
print('heiheihei')
time.sleep(5)
print('heiheihei')
start_time = time.time()
g1 = spawn(heng)
g2 = spawn(ha)
g3 = spawn(heiheihei)
g1.join()
g2.join() # 等待被檢測的任務執行完畢 再往後繼續執行
g3.join()
# heng()
# ha()
# print(time.time() - start_time) # 5.005702018737793
print(time.time() - start_time) # 3.004199981689453 5.005439043045044
3、 協程實作TCP服務端的并發
# 服務端
from gevent import monkey;monkey.patch_all()
import socket
from gevent import spawn
def communication(conn):
while True:
try:
data = conn.recv(1024)
if len(data) == 0: break
conn.send(data.upper())
except ConnectionResetError as e:
print(e)
break
conn.close()
def server(ip, port):
server = socket.socket()
server.bind((ip, port))
server.listen(5)
while True:
conn, addr = server.accept()
spawn(communication, conn)
if __name__ == '__main__':
g1 = spawn(server, '127.0.0.1', 8080)
g1.join()
# 用戶端
from threading import Thread, current_thread
import socket
def x_client():
client = socket.socket()
client.connect(('127.0.0.1',8080))
n = 0
while True:
msg = '%s say hello %s'%(current_thread().name,n)
n += 1
client.send(msg.encode('utf-8'))
data = client.recv(1024)
print(data.decode('utf-8'))
if __name__ == '__main__':
for i in range(500):
t = Thread(target=x_client)
t.start()
總結
"""
理想狀态:
我們可以通過
多程序下面開設多線程
多線程下面再開設協程式
進而使我們的程式執行效率提升
"""