Python 併發程式設計(協程)

2021-10-25 14:33:06 字數 3687 閱讀 4668

本章節主要介紹,使用單執行緒實現併發,即只用乙個主線程(很明顯可利用cpu只有乙個),為此我們需要先回顧下併發的本質:切換+儲存狀態

ps:在介紹程序理論時,提及程序的三種執行狀態,而執行緒才是執行單位,所以也可以將上圖理解為執行緒的三種狀態

單執行緒下併發稱為:協程

特點:

缺點:gevent 是乙個第三方庫,可以輕鬆通過gevent實現併發同步或非同步程式設計,在python內我們使用這個模組,可以讓我們的程式執行,達到乙個協程的效果

使用方式:

import gevent

g1 = gevent.spawn(func,args,kwargs)

g1 = gevent.spawn(func,args,kwargs)

g1.join(

)# 等待g1結束

g2.join(

)# 等待g2結束

# 或者二合一 gevent.joinall([g1,g2])

g1.value # 拿到g1執行func的返回值

遇到io自動切換任務

import gevent

deftest1

(name)

:print

(f' test1 running'

) gevent.sleep(2)

print

(f' test1 stop'

)def

test2

(name)

:print

(f' test2 running'

) gevent.sleep(2)

print

(f' test2 stop'

)g1 = gevent.spawn(test1,

'jack'

)g2 = gevent.spawn(test2,

'tom'

)gevent.joinall(

[g1,g2]

)# 注意,我們如果不等待任務執行結束,那麼遇到阻塞則不會繼續執行了

執行結果:

'''

jack test1 running

tom test2 running

jack test1 stop

tom test2 stop

'''

其中gevent.sleep(2)是gevent模組可以識別的io阻塞

time.sleep(2) 或其它阻塞是gevent模組所不能識別的,所以我們需在檔案的開頭增加(**程式執行前)乙個方法,來解決這個問題

from gevent import monkey;monkey.patch_all(

)# 上面寫法等同於:

# from gevent import monkey

# monkey.patch_all()

import gevent

import time

deftest1

(name)

:print

(f' test1 running'

) time.sleep(2)

print

(f' test1 stop'

)def

test2

(name)

:print

(f' test2 running'

) time.sleep(2)

print

(f' test2 stop'

)g1 = gevent.spawn(test1,

'jack'

)g2 = gevent.spawn(test2,

'tom'

)gevent.joinall(

[g1,g2]

)# 注意,我們如果不等待任務執行結束,那麼遇到阻塞則不會繼續執行了

執行結果

'''

jack test1 running

tom test2 running

jack test1 stop

tom test2 stop

'''

我們可以使用threading.current_thread().getname()來檢視它們是由誰來執行的

from gevent import monkey;monkey.patch_all(

)import gevent

import time

from threading import current_thread

deftest1()

:print

(f' test1 running'

) time.sleep(2)

print

(f' test1 stop'

)def

test2()

:print

(f' test2 running'

) time.sleep(2)

print

(f' test2 stop'

)g1 = gevent.spawn(test1)

g2 = gevent.spawn(test2)

gevent.joinall(

[g1,g2]

)

執行結果

'''

dummythread-1 test1 running

dummythread-2 test2 running

dummythread-1 test1 stop

dummythread-2 test2 stop

'''

結果為:dummythread,表示假執行緒

單執行緒下,遇到io時,演示同步與非同步的效果

from gevent import monkey;monkey.patch_all(

)import gevent

import time

deftask()

: time.sleep(2)

start = time.time(

)for i in

range(5

):task(

)print

('同步耗時:%0.2fs'

%(time.time(

)- start)

)# 10.2s

deftask()

: time.sleep(2)

asy_time = time.time(

)g_lis =

for i in

range(5

):)gevent.joinall(g_lis)

print

('非同步耗時:%0.2fs'

%(time.time(

)- asy_time)

)# 2s

# gevent模組,開啟乙個乙個任務等待時,則切換下乙個任務,這裡每個任務都遇到,所以同時開啟,同時一起都在執行,所以結果為2s

python 併發程式設計 協程 協程介紹

協程 是單執行緒下的併發,又稱微執行緒,纖程。英文名coroutine。一句話說明什麼是執行緒 協程是一種使用者態的輕量級執行緒,即協程是由使用者程式自己控制排程的 需要強調的是 1.python的執行緒屬於核心級別的,即由作業系統控制排程 如單執行緒遇到io或執行時間過長就會被迫交出cpu執行許可...

併發程式設計 協程

一 協程介紹 協程 是單執行緒下的併發,又稱微執行緒,纖程。英文名coroutine。一句話說明什麼是執行緒 協程是一種使用者態的輕量級執行緒,即協程是由使用者程式自己控制排程的。需要強調的是 對比作業系統控制線程的切換,使用者在單執行緒內控制協程的切換 優點如下 缺點如下 總結 必須在只有乙個單執...

python 併發程式設計 協程 greenlet模組

不敢是yield,還是greenlet都沒有實現檢測io,實現遇到io切換效果 如果我們在單個執行緒內有20個任務,要想實現在多個任務之間切換,使用yield生成器的方式過於麻煩 需要先得到初始化一次的生成器,然後再呼叫send。非常麻煩 而使用greenlet模組可以非常簡單地實現這20個任務直接...