正文共:1566?字
預(yù)計閱讀時間:?4?分鐘
工作中遇到一個需求就是必須順序執(zhí)行完一些python方法痕慢,這些方法其原理都是調(diào)用原本就有的shell命令對系統(tǒng)進(jìn)行相關(guān)的操作颤介,但每個shell命令之間是有比較強(qiáng)的依賴的守伸,比如B腳本要正常執(zhí)行右蒲,就必須先成功執(zhí)行了A腳本挺邀,此時就必須在邏輯上確保A腳本對應(yīng)的python方向比B腳本對應(yīng)的python方法是先執(zhí)行的蝠嘉。
雖然說python本身是單線程的,但因?yàn)樵鹃_發(fā)的python系統(tǒng)比較復(fù)雜荚守,所以為了確保絕對的串行運(yùn)行珍德,需要顯示的通過相應(yīng)的邏輯來保證练般,這是使用鎖的一個絕佳處境。
鎖的運(yùn)用
鎖的樸素原理很簡單菱阵,一個資源被鎖鎖住了踢俄,其他進(jìn)程沒有相應(yīng)的鑰匙就無法獲得這個資源,如果該進(jìn)程一定需要這個資源晴及,那么就需要等待其他擁有鎖的進(jìn)程使用完后都办,釋放出來給自己,然后才能繼續(xù)執(zhí)行虑稼。
那為了實(shí)現(xiàn)邏輯上的串行調(diào)用琳钉,利用鎖就可以輕松實(shí)現(xiàn),依舊是A腳本對應(yīng)的方法A要比B腳本對應(yīng)的方法B先調(diào)用蛛倦,那么方法A調(diào)用時歌懒,將資源使用鎖鎖住,只用正在使用該資源的方法A具有鎖的鑰匙溯壶,只有等方法A執(zhí)行完及皂,釋放鎖后,方法B才能獲得鑰匙去調(diào)用相應(yīng)的鎖且改。
這里通過threading中的Lock來實(shí)現(xiàn)一個鎖验烧,通過裝飾器的寫法實(shí)現(xiàn)一個裝飾器,實(shí)現(xiàn)對方法加鎖又跛,如果方法沒有執(zhí)行完碍拆,鎖就不會釋放,此時其他方法就不能繼續(xù)執(zhí)行慨蓝。具體代碼如下:
from threading import Lock
# Program Lock. Program running when it get the program lock
lock = Lock()
def use_lock(func):
? ?def wrapper(*args, **kwargs):
? ? ? ?# get lock
? ? ? ?if lock.acquire():
? ? ? ? ? ?try:
? ? ? ? ? ? ? ?print('%s [%f]'%(func.__name__, time.time()))
? ? ? ? ? ? ? ?return func(*args, **kwargs)
? ? ? ? ? ? ? ?print('%s [%f]' % (func.__name__, time.time()))
? ? ? ? ? ?except:
? ? ? ? ? ? ? ?print('func [%s] error'%(func.__name__))
? ? ? ? ? ? ? ?raise
? ? ? ? ? ?finally:
? ? ? ? ? ? ? ?# release lock, avoid dead lock
? ? ? ? ? ? ? ?lock.release()
? ?return wrapper
使用的使用感混,如下:
@use_lock
def _start(self, mode):
...
為了確保python是串行運(yùn)行對應(yīng)的方法的,這里使用list將方法存放起來礼烈,然后順序傳參調(diào)用弧满,因?yàn)檎{(diào)用的方法被use_lock裝飾器裝飾了,所以當(dāng)?shù)谝粋€方法在運(yùn)行時济丘,第二個方法是無法運(yùn)行的谱秽,而且通過順序獲取list中方法的方式,也很好的提現(xiàn)串行執(zhí)行的想法摹迷,具體代碼如下:
def startServer(self):
? '''
? first, start ssdb
? second, start sgame
? :return:
? '''
? try:
? ? ? #順序調(diào)用有所的方法
? ? ? funcs = [self._start, self._start]
? ? ? #參數(shù)
? ? ? params = [('xxx1',), ('xxx2',)]
? ? ? # sequential execute
? ? ? for funcp in zip(funcs, params):
? ? ? ? ? code,info = funcp[0](*funcp[1])
? ? ? ? ? if code == errorcode:
? ? ? ? ? ? ? return rt_pt(errorcode, 'ssdb and sgame start fail')
? ? ? return rt_pt(successcode, 'ssdb and sgame start success')
? except:
? ? ? print(traceback.print_exc())
? ? ? return rt_pt(errorcode, 'ssdb and sgame start fail')
小結(jié)
通過鎖和list具有順序的特性疟赊,將方法強(qiáng)行串行執(zhí)行,讓強(qiáng)依賴方法之間的正常使用峡碉。