摘要:如果說相比來說,是一種隱式的協(xié)程的話,提供的就更加隱式了。通過調(diào)用可以知道這個鏈表目前的大小。正式因為沒有把底層的協(xié)程直接控制接口開放,而是強(qiáng)買強(qiáng)賣了一個,所以想要在像那樣隨心所欲的操縱協(xié)程還是頗費一番周折的。
如果說greenlet相比generator來說,是一種隱式的協(xié)程的話,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的代碼不同,當(dāng)一個協(xié)程希望切換出去的時候,它無法指定把控制權(quán)交給誰。在stackless的api里沒有父子協(xié)程的概念,無法像generator那樣一個yield跳回到父,也無法向greenlet那樣greenlet.getcurrent().parent找到父然后跳回去。stackless里就一行
stackless.schedule()
尼瑪,這是要往哪里跳?stackless壓根沒有提供底層的協(xié)程給程序員直接使用,它提供的tasklet的api附贈了一個tasklet的scheduler。這個scheduler的調(diào)用方式就是stackless.schedule。scheduler把tasklet串成一個鏈表,每個tasklet都有一個prev一個next,當(dāng)stackless.schedule的時候就取當(dāng)前tasklet的next,把下一個tasklet拉起來執(zhí)行。通過調(diào)用stackless.runcount可以知道這個鏈表目前的大小。可以看到最開始是1,insert之后變成了2,當(dāng)func執(zhí)行完了又變回了1。
正式因為stackless沒有把底層的協(xié)程直接控制接口開放,而是強(qiáng)買強(qiáng)賣了一個scheduler,所以想要在stackless像greenlet那樣隨心所欲的操縱協(xié)程還是頗費一番周折的。最后還是有高人把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
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/37393.html
摘要:從到到再到,各家的語法都不太一樣。底層的實現(xiàn)是,看名字應(yīng)該是的意思。然后在這個基礎(chǔ)上實現(xiàn)了的和的。的的語法風(fēng)格也是類似所以從語法上來說就三類這樣強(qiáng)制要求的為代表的隱式控制權(quán)的為代表強(qiáng)買強(qiáng)賣編碼風(fēng)格的 從generator到greenlet到stackless再到pypy,各家的語法都不太一樣。pypy底層的實現(xiàn)是continulet,看名字應(yīng)該是continuation的意思。然后在這...
摘要:協(xié)程其實就是一個可中途中斷,由外部來控制執(zhí)行進(jìn)程的函數(shù)。這些第三方的選擇的共同特點是協(xié)程的都是隱式的。這就是顯示控制和隱式控制的區(qū)別。本文討論的協(xié)程就是這一種,后面會逐漸展開到如何利用這種顯示控制的協(xié)程來解決阻塞和流程阻塞的問題。 Python官方的實現(xiàn)里,協(xié)程只有g(shù)enerator這一招。協(xié)程其實就是一個可中途中斷,由外部來控制執(zhí)行進(jìn)程的函數(shù)。除了官方的generator,還有很多第...
摘要:特別是最火的協(xié)程框架也無法保存狀態(tài),讓人非常惋惜。但是因為棧的本身無法持久化,所以也就無法持久化。其難度在于,假設(shè)整個要持久化的調(diào)用棧全部都是內(nèi)的,比如純的。采取的是暴力地把整個棧區(qū)域拷貝到上的方式來保存其狀態(tài)。 python主流的協(xié)程實現(xiàn)有五種: cPython的generator cPython的greenlet cPython的fibers stackless python ...
閱讀 3115·2021-10-13 09:40
閱讀 3971·2021-09-22 15:51
閱讀 1512·2021-09-22 15:48
閱讀 1081·2021-09-06 15:00
閱讀 1806·2019-08-30 15:43
閱讀 2372·2019-08-29 18:35
閱讀 1684·2019-08-29 16:18
閱讀 3630·2019-08-29 12:49