程序:資源單位
執行緒:執行單位
協程:單執行緒下實現併發
併發:切換+儲存狀態
程式設計師自己通過**自己檢測程式中的io
一旦遇到了io自己通過**切換
給作業系統的感覺就是你這個執行緒沒有任何的io 從而提公升**的執行效率
切換+儲存狀態一定能夠提公升效率嗎?
1.當任務是io密集型的情況下 提公升效率
2.當任務是計算密集型的情況下 降低效率
接下來 我們進行驗證
1.在計算密集型的情況下,通過切換+儲存狀態 效率到底是降低了還是提公升了呢?
#序列執行 0.8540799617767334
import
time
deffunc1():
for i in range(10000000):
i+1deffunc2():
for i in range(10000000):
i+1start =time.time()
func1()
func2()
stop =time.time()
print(stop - start)
#基於yield併發執行 1.3952205181121826
import
time
deffunc1():
while
true:
10000000+1
yield
deffunc2():
g=func1()
for i in range(10000000):
time.sleep(100) #
模擬io,yield並不會捕捉到並自動切換
i+1next(g)
start=time.time()
func2()
stop=time.time()
print(stop-start)
根據執行時間來看 明顯效率是降低了
2.在io密集型的情況下,通過切換+儲存狀態 效率到底是降低了還是提公升了呢?
首先我們需要找到乙個能夠識別io的工具,遇到io就可以自動的切換
這裡我們就用到了gevent模組
這是序列的執行結果:
from gevent importmonkey;monkey.patch_all()
from gevent import
spawn
import
time
'''注意 gevent模組沒辦法自動識別 time.sleep 等io情況
需要你手動配置乙個引數
'''def
heng():
print('哼!'
) time.sleep(2)
print('哼!'
)def
ha():
print('哈!'
) time.sleep(3)
print('哈!'
)start =time.time()
heng()
ha()
print(time.time()-start)
#5.041796445846558
下面是通過切換+儲存狀態來執行 利用gevent模組
from gevent importmonkey;monkey.patch_all()
from gevent import
spawn
import
time
'''注意 gevent模組沒辦法自動識別 time.sleep 等io情況
需要你手動配置乙個引數
'''def
heng():
print('哼!'
) time.sleep(2)
print('哼!'
)def
ha():
print('哈!'
) time.sleep(3)
print('哈!'
)start =time.time()
g=spawn(heng)
g1 =spawn(ha)
g.join()
g1.join()
print(time.time()-start)
#3.041301727294922
明顯的看出在io密集型的情況下 切換+儲存狀態能夠提公升效率
利用協程實現併發
實現tcp服務端的併發
server端
importsocket
from gevent import
monkey;monkey.patch_all()
from gevent import
spawn
sk =socket.socket()
sk.bind((
'127.0.0.1
', 8080))
sk.listen()
deftalk(conn):
while
true:
try:
data = conn.recv(1024)
if len(data) == 0 :break
print(data.decode('
utf-8'))
conn.send(b'hi
')except
connectionreseterror as e:
(e)
break
conn.close()
defserver():
while
true:
conn,addr =sk.accept()
spawn(talk,conn)
if__name__ == '
__main__':
res =spawn(server)
res.join()
client端 起了400個執行緒
from threading importthread
import
socket
defclient():
sk =socket.socket()
sk.connect((
'127.0.0.1
',8080))
while
true:
sk.send(b
'hello')
data = sk.recv(1024).decode('
utf-8')
(data)
for i in range(400):
t = thread(target=client)
t.start()
併發程式設計之協程
協程 是單執行緒下的併發,一句話說明什麼是執行緒 協程是一種使用者態的輕量級執行緒,即協程是由使用者程式自己控制排程的。對比作業系統控制線程的切換,使用者在單執行緒內控制協程的切換 優點 1.協程的切換開銷更小,屬於程式級別的切換,作業系統完全感知不到,因而更加輕量級 2.單執行緒內就可以實現併發的...
Python 之併發程式設計之協程
def gen for i in range 10 yield i 初始化生成七函式 返回生成器物件 簡稱生成器 mygen gen for i in mygen print i 1 用協程改寫成生產者消費者 def producer for i in range 100 yield i def c...
併發程式設計 協程
一 協程介紹 協程 是單執行緒下的併發,又稱微執行緒,纖程。英文名coroutine。一句話說明什麼是執行緒 協程是一種使用者態的輕量級執行緒,即協程是由使用者程式自己控制排程的。需要強調的是 對比作業系統控制線程的切換,使用者在單執行緒內控制協程的切換 優點如下 缺點如下 總結 必須在只有乙個單執...