併發程式設計之 協程

2022-06-29 22:33:18 字數 3597 閱讀 1101

程序:資源單位

執行緒:執行單位

協程:單執行緒下實現併發

併發:切換+儲存狀態

程式設計師自己通過**自己檢測程式中的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 import

monkey;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 import

monkey;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端

import

socket

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:

print

(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 import

thread

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')

print

(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。一句話說明什麼是執行緒 協程是一種使用者態的輕量級執行緒,即協程是由使用者程式自己控制排程的。需要強調的是 對比作業系統控制線程的切換,使用者在單執行緒內控制協程的切換 優點如下 缺點如下 總結 必須在只有乙個單執...