摘要:如果說相比來說,是一種隱式的協程的話,提供的就更加隱式了。通過調用可以知道這個鏈表目前的大小。正式因為沒有把底層的協程直接控制接口開放,而是強買強賣了一個,所以想要在像那樣隨心所欲的操縱協程還是頗費一番周折的。
如果說greenlet相比generator來說,是一種隱式的協程的話,stackless python提供的api就更加隱式了。
import stackless def func(a, b): print("2 current: %s" % stackless.getcurrent()) print("2 main: %s" % stackless.getmain()) print("2 prev: %s" % stackless.getcurrent().prev) print("2 next: %s" % stackless.getcurrent().next) print(a) stackless.schedule() print(b) stackless.schedule() print("finished") t = stackless.tasklet() t.bind(func, ("hello",), {"b": "world"}) print("1 current: %s" % stackless.getcurrent()) print("1 main: %s" % stackless.getmain()) print("1 run count: %s" % stackless.runcount) t.insert() print("2 run count: %s" % stackless.runcount) stackless.schedule() print("scheduled back to main") stackless.schedule() print("2 run count: %s" % stackless.runcount) stackless.schedule() print("2 run count: %s" % stackless.runcount)
這段代碼的輸出是這樣的:
1 current: <_stackless.tasklet object at 0x7ffa189b71a0> 1 main: <_stackless.tasklet object at 0x7ffa189b71a0> 1 run count: 1 2 run count: 2 2 current: <_stackless.tasklet object at 0x7ffa18885f30> 2 main: <_stackless.tasklet object at 0x7ffa189b71a0> 2 prev: <_stackless.tasklet object at 0x7ffa189b71a0> 2 next: <_stackless.tasklet object at 0x7ffa189b71a0> hello scheduled back to main world 2 run count: 2 finished 2 run count: 1
與greenlet的代碼不同,當一個協程希望切換出去的時候,它無法指定把控制權交給誰。在stackless的api里沒有父子協程的概念,無法像generator那樣一個yield跳回到父,也無法向greenlet那樣greenlet.getcurrent().parent找到父然后跳回去。stackless里就一行
stackless.schedule()
尼瑪,這是要往哪里跳?stackless壓根沒有提供底層的協程給程序員直接使用,它提供的tasklet的api附贈了一個tasklet的scheduler。這個scheduler的調用方式就是stackless.schedule。scheduler把tasklet串成一個鏈表,每個tasklet都有一個prev一個next,當stackless.schedule的時候就取當前tasklet的next,把下一個tasklet拉起來執行。通過調用stackless.runcount可以知道這個鏈表目前的大小。可以看到最開始是1,insert之后變成了2,當func執行完了又變回了1。
正式因為stackless沒有把底層的協程直接控制接口開放,而是強買強賣了一個scheduler,所以想要在stackless像greenlet那樣隨心所欲的操縱協程還是頗費一番周折的。最后還是有高人把stackless的高階接口重新封裝成了和greenlet一樣的底層接口了。目的就是為了讓gevent可以跑在stackless python上(雖然比cPython版本的還慢):
http://syncless.googlecode.com/svn/trunk/syncless/greenlet_using_stackless.py
另外有有一個反過來的版本,在greenlet上封裝了一個和stackless python一樣的帶scheduler的api
http://syncless.googlecode.com/svn/trunk/syncless/greenstackless.py
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/37393.html
摘要:從到到再到,各家的語法都不太一樣。底層的實現是,看名字應該是的意思。然后在這個基礎上實現了的和的。的的語法風格也是類似所以從語法上來說就三類這樣強制要求的為代表的隱式控制權的為代表強買強賣編碼風格的 從generator到greenlet到stackless再到pypy,各家的語法都不太一樣。pypy底層的實現是continulet,看名字應該是continuation的意思。然后在這...
摘要:協程其實就是一個可中途中斷,由外部來控制執行進程的函數。這些第三方的選擇的共同特點是協程的都是隱式的。這就是顯示控制和隱式控制的區別。本文討論的協程就是這一種,后面會逐漸展開到如何利用這種顯示控制的協程來解決阻塞和流程阻塞的問題。 Python官方的實現里,協程只有generator這一招。協程其實就是一個可中途中斷,由外部來控制執行進程的函數。除了官方的generator,還有很多第...
摘要:特別是最火的協程框架也無法保存狀態,讓人非常惋惜。但是因為棧的本身無法持久化,所以也就無法持久化。其難度在于,假設整個要持久化的調用棧全部都是內的,比如純的。采取的是暴力地把整個棧區域拷貝到上的方式來保存其狀態。 python主流的協程實現有五種: cPython的generator cPython的greenlet cPython的fibers stackless python ...
閱讀 3095·2021-10-13 09:40
閱讀 3945·2021-09-22 15:51
閱讀 1493·2021-09-22 15:48
閱讀 1060·2021-09-06 15:00
閱讀 1790·2019-08-30 15:43
閱讀 2356·2019-08-29 18:35
閱讀 1667·2019-08-29 16:18
閱讀 3612·2019-08-29 12:49