摘要:比如里可以直接把執行權交給,而完全不知情。雖然不能和多線程相比,但是效果是類似的。對于多線程的代碼,是任何一行代碼都可能與其他線程并行。加上協程之間有共享狀態的話,一定程度上會產生類似多線程的并發讀寫狀態的。
前面講generator是顯式的協程的時候缺一個例子,現在補上
def parent_generator(): print("hello") yield from sub_generator() print("world") def sub_generator(): yield 1 gen = parent_generator() gen.send(None) gen.send(None)
這里可以看出parent_generator為了在hello和world之間中斷,必須顯式的用yield from把控制權從自己手里轉交給調用者。如果parent_generator沒有使用yield,那么sub_generator里即使有yield也無法使得parent_generator的執行權轉交出去。所以從視覺上可以一步了然的指導一個函數中哪些調用是產生了switch的,哪些是肯定順序執行的。有一點類似Haskell里給所有I/O操作加類型標簽的味道。
from greenlet import greenlet def parent(): print("hello") sub() print("world") def sub(): greenlet.getcurrent().parent.switch() g = greenlet(parent) g.switch() print("here is switched from the sub generator") g.switch()
這段代碼的輸出是
hello here is switched from the sub generator world
改用greenlet之后,協程之間的跳轉就變得非常隨意了。比如sub里可以直接把執行權交給main,而parent完全不知情。從視覺上來看parent的實現里完全不能知道在sub內部發生了switch。
雖然不能和多線程相比,但是效果是類似的。對于多線程的代碼,是任何一行代碼都可能與其他線程并行。類似greenlet的隱式的協程,雖然不是每一行代碼都可能產生switch。雖然產生switch的地方其實和用yield寫是一樣多,而且也是一樣固定的。但是因為缺少強制的yield,使得在不閱讀被調用函數內部的實現的前提下,無法提前知道這個調用是否會產生執行權的遷移。加上協程之間有共享狀態的話,一定程度上會產生類似多線程的并發讀寫狀態的bug。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/37394.html
摘要:如果說相比來說,是一種隱式的協程的話,提供的就更加隱式了。通過調用可以知道這個鏈表目前的大小。正式因為沒有把底層的協程直接控制接口開放,而是強買強賣了一個,所以想要在像那樣隨心所欲的操縱協程還是頗費一番周折的。 如果說greenlet相比generator來說,是一種隱式的協程的話,stackless python提供的api就更加隱式了。 import stackless def...
摘要:從到到再到,各家的語法都不太一樣。底層的實現是,看名字應該是的意思。然后在這個基礎上實現了的和的。的的語法風格也是類似所以從語法上來說就三類這樣強制要求的為代表的隱式控制權的為代表強買強賣編碼風格的 從generator到greenlet到stackless再到pypy,各家的語法都不太一樣。pypy底層的實現是continulet,看名字應該是continuation的意思。然后在這...
摘要:協程其實就是一個可中途中斷,由外部來控制執行進程的函數。這些第三方的選擇的共同特點是協程的都是隱式的。這就是顯示控制和隱式控制的區別。本文討論的協程就是這一種,后面會逐漸展開到如何利用這種顯示控制的協程來解決阻塞和流程阻塞的問題。 Python官方的實現里,協程只有generator這一招。協程其實就是一個可中途中斷,由外部來控制執行進程的函數。除了官方的generator,還有很多第...
摘要:常規版本的的是不可以被持久化保存的。在流程被阻塞的時候比如需要審批老板不在把協程持久化成入庫,等流程不再阻塞的時候把協程重新從數據庫里拉起來繼續執行。 常規版本的Python的generator是不可以被持久化保存的。但是stackless和pypy這兩個修改版本的Python解釋器可以。下面這段代碼演示了如何把一個執行中的函數持久化保存,然后過段時間再把函數從上次執行到的地方原樣拉起...
摘要:特別是最火的協程框架也無法保存狀態,讓人非常惋惜。但是因為棧的本身無法持久化,所以也就無法持久化。其難度在于,假設整個要持久化的調用棧全部都是內的,比如純的。采取的是暴力地把整個棧區域拷貝到上的方式來保存其狀態。 python主流的協程實現有五種: cPython的generator cPython的greenlet cPython的fibers stackless python ...
閱讀 3794·2021-11-17 09:33
閱讀 2011·2021-10-26 09:51
閱讀 1527·2021-09-29 09:44
閱讀 1678·2019-08-30 15:55
閱讀 1447·2019-08-30 15:52
閱讀 2325·2019-08-30 15:43
閱讀 3432·2019-08-29 17:00
閱讀 2302·2019-08-29 16:23