高階程式設計技巧 學習筆記
1.1、同步 & 非同步
1.2、阻塞 & 非阻塞
2.1、什麼是協程?
協程,又稱微執行緒。協程是 python 個中另外一種實現多工的方式,只不過比執行緒更小占用更小執行單元(理解為需要的資源)。
2.2、python中的協程大概經歷了如下三個階段:
最初的生成器變形yield / send
yield from
在最近的 python3.5 版本中引入async / await
關鍵字
3.1、使用 greenlet 完成多工
from greenlet import greenlet
import time
# 協程利用程式的 io 來切換任務
# 這裡簡單一點, 就用 sleep 延遲代替 io
defdemo1()
:for i in
range(5
):print
("demo1"
) time.sleep(
0.5)
defdemo2()
:for i in
range(5
):print
("demo2"
) time.sleep(
0.5)
gr1 = greenlet(demo1)
gr2 = greenlet(demo2)
gr1.switch(
)gr2.switch(
)
執行發現,程式先執行完第乙個任務再執行下乙個任務?說明在開始執行任務後並沒有切換任務。
修改任務,使其完成切換操作。
from greenlet import greenlet
import time
# 協程利用程式的 io 來切換任務
# 這裡簡單一點, 就用 sleep 延遲代替 io
defdemo1()
:for i in
range(5
):print
("demo1"
)# 執行 "任務2", (相當於從任務1切換到任務2)
gr2.switch(
) time.sleep(
0.5)
defdemo2()
:for i in
range(5
):print
("demo2"
)# 執行 "任務1"
gr1.switch(
) time.sleep(
0.5)
gr1 = greenlet(demo1)
gr2 = greenlet(demo2)
# 執行 "任務1"
gr1.switch(
)
存在問題,每次執任務時都要新增切換任務的語句,這麼做不緊麻煩而且還固定了每個任務的執行順序。
使用 gevent 可以更好的解決這個問題。
3.2、使用 gevent 完成多工
import gevent
import time
deff1
(n):
for i in
range
(n):
print
(gevent.getcurrent(
), i)
time.sleep(
0.5)
deff2
(n):
for i in
range
(n):
print
(gevent.getcurrent(
), i)
time.sleep(
0.5)
deff3
(n):
for i in
range
(n):
print
(gevent.getcurrent(
), i)
time.sleep(
0.5)
g1 = gevent.spawn(f1,5)
g2 = gevent.spawn(f2,5)
g3 = gevent.spawn(f3,5)
g1.join(
)g2.join(
)g3.join(
)
嗯?這列印的結果不還是一樣嗎?
其實是因為gevent並不認識time.sleep()
。要想再使用gevent的時候,實現延遲,需要使用gevent.sleep()
。
import gevent
import time
deff1
(n):
for i in
range
(n):
print
(gevent.getcurrent(
), i)
gevent.sleep(
0.5)
deff2
(n):
for i in
range
(n):
print
(gevent.getcurrent(
), i)
gevent.sleep(
0.5)
deff3
(n):
for i in
range
(n):
print
(gevent.getcurrent(
), i)
gevent.sleep(
0.5)
g1 = gevent.spawn(f1,5)
g2 = gevent.spawn(f2,5)
g3 = gevent.spawn(f3,5)
g1.join(
)g2.join(
)g3.join(
)
用gevent.sleep()
替換time.sleep()
確實可以解決問題,但是如果專案中需要修改的地方有很多,那手動去乙個乙個修改顯然是不可取的。此時,就要用到monkey.patch_all()
了。
import gevent
import time
from gevent import monkey
# 將程式中用到的耗時操作, 都換為 gevent 中實現的模組
# 相當於打了乙個補丁
monkey.patch_all(
)def
f1(n)
:for i in
range
(n):
print
(gevent.getcurrent(
), i)
time.sleep(
0.5)
deff2
(n):
for i in
range
(n):
print
(gevent.getcurrent(
), i)
time.sleep(
0.5)
deff3
(n):
for i in
range
(n):
print
(gevent.getcurrent(
), i)
time.sleep(
0.5)
g1 = gevent.spawn(f1,5)
g2 = gevent.spawn(f2,5)
g3 = gevent.spawn(f3,5)
g1.join(
)g2.join(
)g3.join(
)
多工 協程
示例 import time defwork1 while true print 正在掃地 yield defwork2 while true print 正在搬磚 yield w1 work1 w2 work2 協程肯定是併發執行 while true next w1 next w2 greenl...
Python 多工之協程(3)實現多工
學習理解迭代器和生成器之後,開始使用協程來實現多工 當乙個函式中包含yield關鍵字,那麼這個函式就不再是乙個普通的函式,它的返回值是乙個生成器物件。我們可以使用next 或send 函式來啟動喚醒生成器物件,當程式第一次執行到yield時,程式暫停執行,並返回yield後邊跟的變數,當再次喚醒時,...
多工18 協程
協程,又稱微執行緒,纖程。英文名coroutine。協程是python個中另外一種實現多工的方式,只不過比執行緒更小占用更小執行單元 理解為需要的資源 為啥說它是乙個執行單元,因為它自帶cpu上下文。這樣只要在合適的時機,我們可以把乙個協程 切換到另乙個協程。只要這個過程中儲存或恢復 cpu上下文那...