基于python生成器封裝的協(xié)程類
自從python2.2提供了yield關(guān)鍵字之后,python的生成器的很大一部分用途就是可以用來構(gòu)建協(xié)同程序,能夠?qū)⒑瘮?shù)掛起返回中間值并能從上次離開的地方繼續(xù)執(zhí)行。python2.5的時候,這種生成器更加接近完全的協(xié)程,因?yàn)樘峁┝藢⒅岛彤惓鬟f回到一個繼續(xù)執(zhí)行的函數(shù)中,當(dāng)?shù)却善鞯臅r候,生成器能返回控制。
python提供的生成器設(shè)施:
- yield:能夠?qū)⒆约簰炱?,并提供一個返回值給等待方
- send:喚起一個被掛起的生成器,并能夠傳遞一個參數(shù),可以在生成器中拋出異常
- next:本質(zhì)上相當(dāng)于send(None),對每個生成器的第一次調(diào)用必須不能傳遞參數(shù)
- close:主動退出一個生成器
python封裝
雖然python3提供了asyncio這樣的異步IO庫,而且也有g(shù)reenlet等其他協(xié)程庫,但目前的需求并不是實(shí)際的網(wǎng)絡(luò)IO并發(fā)操作,而是需要模擬狀態(tài)機(jī)的運(yùn)行,因此使用協(xié)程可以很方便的模擬,并加入認(rèn)為的控制,下面是封裝的一個python類。
class Coroutine(object): """ Base class of the general coroutine object """ STATE_RUNNING = 0 STATE_WAITING = 1 STATE_CLOSING = 2 def __init__(self): self.state = Coroutine.STATE_WAITING self.started = False self.args = None self.routine = self._co() def _co(self): self.ret = None while True: self.args = yield self.ret if not self.started: self.started = True continue else: self.state = Coroutine.STATE_RUNNING self.ret = self.run(self.args) if self.state == Coroutine.STATE_CLOSING: break self.state = Coroutine.STATE_WAITING def start(self): """ Start the generator """ if self.routine is None: raise RuntimeError('NO task to start running!') self.started = True self.routine.next() def finish(self): """ Finish the execution of this routine """ self.state = Coroutine.STATE_CLOSING self.routine.close() def run(self, args): """ The runing method to be executed every once time""" raise NotImplementedError def execute(self, arg_obj): """ Awake this routine to execute once time """ return self.routine.send(arg_obj)
基于上述封裝,下面實(shí)現(xiàn)了一個協(xié)同的生產(chǎn)者消費(fèi)者示例:
class ProducerCoroutine(Coroutine): """ The Producer concrete coroutine """ def __init__(self, cnsmr): if not isinstance(cnsmr, Coroutine): raise RuntimeError('Consumer is not a Coroutine object') self.consumer = cnsmr self.consumer.start() super(ProducerCoroutine, self).__init__() def run(self, args): print 'produce ', args ret = self.consumer.execute(args) print 'consumer return:', ret def __call__(self, args): """ Custom method for the specific logic """ self.start() while len(args) > 0: p = args.pop() self.execute(p) self.finish() class ConsumerCoroutine(Coroutine): """ The Consumer concrete coroutine """ def __init__(self): super(ConsumerCoroutine, self).__init__() def run(self, args): print 'consumer get args: ', args return 'hahaha' + repr(args)
運(yùn)行結(jié)果如下:
produce 4 consumer get args: 4 consumer return: hahaha4 produce 3 consumer get args: 3 consumer return: hahaha3 produce 2 consumer get args: 2 consumer return: hahaha2 produce 1 consumer get args: 1 consumer return: hahaha1 produce 0 consumer get args: 0 consumer return: hahaha0
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳談在flask中使用jsonify和json.dumps的區(qū)別
下面小編就為大家分享一篇詳談在flask中使用jsonify和json.dumps的區(qū)別,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03使用llama?Index幫你訓(xùn)練pdf的示例詳解
這篇文章主要為大家介紹了使用llama?Index?幫你訓(xùn)練pdf,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Pandas數(shù)據(jù)處理庫畫圖與文件讀取使用示例
這篇文章主要為大家介紹了Pandas數(shù)據(jù)處理庫畫圖與文件讀取使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10windows下pycharm搭建spark環(huán)境并成功運(yùn)行 附源碼
這篇文章主要介紹了windows下pycharm搭建spark環(huán)境并成功運(yùn)行 附源碼,本文分步驟給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04Python中2種常用數(shù)據(jù)可視化庫Bokeh和Altair使用示例詳解
本文對Python中兩個常用的數(shù)據(jù)可視化庫?Bokeh?和?Altair?進(jìn)行了比較和探討,通過對它們的特點(diǎn)、優(yōu)缺點(diǎn)以及使用示例的詳細(xì)分析,讀者可以更好地了解這兩個庫的功能和適用場景,從而更好地選擇合適的庫來進(jìn)行數(shù)據(jù)可視化工作,感興趣的朋友跟隨小編一起看看吧2024-04-04