摘要:常規(guī)版本的的是不可以被持久化保存的。在流程被阻塞的時(shí)候比如需要審批老板不在把協(xié)程持久化成入庫,等流程不再阻塞的時(shí)候把協(xié)程重新從數(shù)據(jù)庫里拉起來繼續(xù)執(zhí)行。
常規(guī)版本的Python的generator是不可以被持久化保存的。但是stackless和pypy這兩個(gè)修改版本的Python解釋器可以。下面這段代碼演示了如何把一個(gè)執(zhí)行中的函數(shù)持久化保存,然后過段時(shí)間再把函數(shù)從上次執(zhí)行到的地方原樣拉起。從效果上來說,有點(diǎn)類似于Vmware虛擬機(jī)的snapshot的功能:
import cPickle as pickle def generator_can_be_used_as_workflow(): yield "do something" is_approved = yield "ask boss for permission" if is_approved: yield "do another after approved" else: yield "do another after rejected" workflow = generator_as_workflow_engine() print(workflow.next()) print(workflow.next()) # boss is not available now persisted_workflow = pickle.dumps(workflow) print("persisted workflow is like this: [%s ...]" % persisted_workflow.replace(" ", " ")[:150]) # several hours later, boss come back workflow = pickle.loads(persisted_workflow) print(workflow.send(True)) # I approve
這段代碼的輸出是
do something ask boss for permission persisted workflow is like this: [cstackless._wrap generator p1 (tRp2 (cstackless._wrap frame p3 (cstackless._wrap code p4 (I0 I1 I1 I99 S"dx01x00Vx01dx02x00V}x00x00|x00x00rx ...] do another after approved
利用這個(gè)原理,我們可以把一個(gè)需要運(yùn)行很長(zhǎng)時(shí)間的流程用協(xié)程的方式來實(shí)現(xiàn)。在流程被阻塞的時(shí)候(比如需要審批老板不在)把協(xié)程持久化成string入庫,等流程不再阻塞的時(shí)候把協(xié)程重新從數(shù)據(jù)庫里拉起來繼續(xù)執(zhí)行。優(yōu)點(diǎn)自然是輕量簡(jiǎn)單隨意強(qiáng)大,缺點(diǎn)也是隨意強(qiáng)大導(dǎo)致流程狀態(tài)不可被外部直接解讀和操作,也無法實(shí)現(xiàn)運(yùn)行中的流程實(shí)例的代碼升級(jí)。所以,這種工作流用在電子政務(wù),或者辦公自動(dòng)化等強(qiáng)人機(jī)交互的領(lǐng)域(需要極高的靈活性)是不合適的。在運(yùn)維的發(fā)布變更這樣的場(chǎng)合下,主要是調(diào)度系統(tǒng)與系統(tǒng),機(jī)器與機(jī)器這樣比較固定且相對(duì)短暫的流程還是比較方便的。
ps:webwork使用的RIFE,是我所知最早的使用協(xié)程的流程引擎
下面是一段演示用pypy的greenlet,控制流程前進(jìn)和回退的例子:
import greenlet if "__main__" == __name__: root = greenlet.getcurrent() def g(): print("enter g") mystack = "special-g-stack" greenlet.getcurrent().parent.switch() print("leave g") def f(): greenlet_g = greenlet.greenlet(g) greenlet_g.switch() root.switch() print("a") greenlet_g.switch() root.switch() print("b") root.switch() print("c") f_greenlet = greenlet.greenlet(f) f_greenlet.switch() f_greenlet_v1 = pickle.dumps(f_greenlet) print("is greenlet g also pickled? %s" % ("special-g-stack" in f_greenlet_v1)) f_greenlet = pickle.loads(f_greenlet_v1) f_greenlet.switch() f_greenlet_v2 = pickle.dumps(f_greenlet) f_greenlet.switch() f_greenlet_v3 = pickle.dumps(f_greenlet) pickle.loads(f_greenlet_v1).switch() pickle.loads(f_greenlet_v3).switch()
輸出是:
enter g is greenlet g also pickled? True a leave g b a leave g c
通過loads不同版本的流程狀態(tài),可以在各個(gè)階段里來回切換。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/37378.html
摘要:本文先回顧生成器,然后過渡到協(xié)程編程。其作用主要體現(xiàn)在三個(gè)方面數(shù)據(jù)生成生產(chǎn)者,通過返回?cái)?shù)據(jù)數(shù)據(jù)消費(fèi)消費(fèi)者,消費(fèi)傳來的數(shù)據(jù)實(shí)現(xiàn)協(xié)程。解決回調(diào)地獄的方式主要有兩種和協(xié)程。重點(diǎn)應(yīng)當(dāng)關(guān)注控制權(quán)轉(zhuǎn)讓的時(shí)機(jī),以及協(xié)程的運(yùn)作方式。 轉(zhuǎn)載請(qǐng)注明文章出處: https://tlanyan.me/php-review... PHP回顧系列目錄 PHP基礎(chǔ) web請(qǐng)求 cookie web響應(yīng) sess...
摘要:特別是最火的協(xié)程框架也無法保存狀態(tài),讓人非常惋惜。但是因?yàn)闂5谋旧頍o法持久化,所以也就無法持久化。其難度在于,假設(shè)整個(gè)要持久化的調(diào)用棧全部都是內(nèi)的,比如純的。采取的是暴力地把整個(gè)棧區(qū)域拷貝到上的方式來保存其狀態(tài)。 python主流的協(xié)程實(shí)現(xiàn)有五種: cPython的generator cPython的greenlet cPython的fibers stackless python ...
摘要:是之后引入的標(biāo)準(zhǔn)庫的,這個(gè)包使用事件循環(huán)驅(qū)動(dòng)的協(xié)程實(shí)現(xiàn)并發(fā)。沒有能從外部終止線程,因?yàn)榫€程隨時(shí)可能被中斷。上一篇并發(fā)使用處理并發(fā)我們介紹過的,在中,只是調(diào)度執(zhí)行某物的結(jié)果。 asyncio asyncio 是Python3.4 之后引入的標(biāo)準(zhǔn)庫的,這個(gè)包使用事件循環(huán)驅(qū)動(dòng)的協(xié)程實(shí)現(xiàn)并發(fā)。asyncio 包在引入標(biāo)準(zhǔn)庫之前代號(hào) Tulip(郁金香),所以在網(wǎng)上搜索資料時(shí),會(huì)經(jīng)??吹竭@種花的...
摘要:很長(zhǎng)一段時(shí)間,我都很天真的認(rèn)為,特別是以為代表的庫,才是協(xié)程的樂土。里是沒法實(shí)現(xiàn)協(xié)程,更別說實(shí)現(xiàn)這樣可以的協(xié)程的。咱真的是太井底之蛙了。不完全列表如下還有一個(gè)據(jù)作者說是最的這些協(xié)程庫的實(shí)現(xiàn)方式都是類似的,都是通過字節(jié)碼生成達(dá)到的目的。 很長(zhǎng)一段時(shí)間,我都很天真的認(rèn)為python,特別是以gevent為代表的庫,才是協(xié)程的樂土。Java里是沒法實(shí)現(xiàn)協(xié)程,更別說實(shí)現(xiàn)stackless py...
摘要:所以與多線程相比,線程的數(shù)量越多,協(xié)程性能的優(yōu)勢(shì)越明顯。值得一提的是,在此過程中,只有一個(gè)線程在執(zhí)行,因此這與多線程的概念是不一樣的。 真正有知識(shí)的人的成長(zhǎng)過程,就像麥穗的成長(zhǎng)過程:麥穗空的時(shí)候,麥子長(zhǎng)得很快,麥穗驕傲地高高昂起,但是,麥穗成熟飽滿時(shí),它們開始謙虛,垂下麥芒。 ——蒙田《蒙田隨筆全集》 上篇論述了關(guān)于python多線程是否是雞肋的問題,得到了一些網(wǎng)友的認(rèn)可,當(dāng)然也有...
閱讀 2286·2021-11-23 09:51
閱讀 5681·2021-09-22 15:39
閱讀 3355·2021-09-02 15:15
閱讀 3506·2019-08-30 15:54
閱讀 2364·2019-08-30 15:53
閱讀 1404·2019-08-30 14:04
閱讀 2459·2019-08-29 18:33
閱讀 2378·2019-08-29 13:08