對(duì)Python的多進(jìn)程鎖的使用方法詳解
很多時(shí)候,我們需要在多個(gè)進(jìn)程中同時(shí)寫(xiě)一個(gè)文件,如果不加鎖機(jī)制,就會(huì)導(dǎo)致寫(xiě)文件錯(cuò)亂
這個(gè)時(shí)候,我們可以使用multiprocessing.Lock()
我一開(kāi)始是這樣使用的:
import multiprocessing lock = multiprocessing.Lock() class MatchProcess(multiprocessing.Process): def __init__(self, threadId, mfile, lock): multiprocessing.Process.__init__(self) self.threadId = threadId self.mfile = mfile self.lock = lock def run(self): while True: self.lock.acquire() try: self.mfile.write('111111111111111111' + '\n') finally: self.lock.release() if __name__ == '__main__': mf = open('test.lst', 'w') for i in range(15): p = MatchProcess(i, mf, lock) p.start()
發(fā)現(xiàn)這種方式,鎖并沒(méi)有起作用, 文件內(nèi)容依然出現(xiàn)了錯(cuò)亂(注意,我這里寫(xiě)的1111是示例,我的代碼實(shí)際寫(xiě)的其他內(nèi)容)
所以這種方式,雖然lock通過(guò)參數(shù)傳到了每個(gè)進(jìn)程中,但是我們知道進(jìn)程之間是不共享內(nèi)存的,所以我理解應(yīng)該是每個(gè)進(jìn)程獲得的鎖其實(shí)是不同的, 所以無(wú)法對(duì)寫(xiě)文件起到加鎖的效果
進(jìn)程池是否可行呢,于是做了如下嘗試
def run(line): lock.acquire() try: mfile.write('111111111111111111' + '\n') finally: lock.release() sf = open('test.lst', 'r') data_lst = list() for line in sf: line = line.strip() data_lst.append(line) pool = Pool(15) pool.map_async(run, data_lst) #map_async方法會(huì)將data_lst這個(gè)可迭代的對(duì)象里面的每個(gè)元素依次傳入run方法來(lái)執(zhí)行 pool.close() pool.join() print 'over'
但是注意:
pool.close() pool.join()
這兩行代碼必不可少,否則,主進(jìn)程執(zhí)行完畢后會(huì)退出,導(dǎo)致整個(gè)進(jìn)程結(jié)束
所以在整個(gè)進(jìn)程全部執(zhí)行完畢后,才會(huì)打印出over
但是這種方式,發(fā)現(xiàn),鎖仍然不起作用
最后采用了如下方式:
def run(line): mfile = open('test2.lst', 'a') lock.acquire() try: mfile.write('111111111111111111' + '\n') finally: lock.release() sf = open('test.lst', 'r') data_lst = list() for line in sf: line = line.strip() data_lst.append(line) pList = [] for line in line_lst: p = multiprocessing.Process(target=run, args=(line, lock)) p.start() pList.append(p) for p in pList: p.join()
是親測(cè)發(fā)現(xiàn),這種方式,鎖的確起作用了,在每次寫(xiě)入數(shù)據(jù)量很大的情況下,速度很慢
但是一個(gè)比較惡心的問(wèn)題是,我一開(kāi)始試圖將文件打開(kāi)后通過(guò)Process對(duì)象的args參數(shù)傳入到run方法中,但是發(fā)現(xiàn)數(shù)據(jù)無(wú)法寫(xiě)入到文件中,見(jiàn)鬼,這個(gè)問(wèn)題我還沒(méi)搞明白
無(wú)耐,只能采取上面的笨方法,在每次寫(xiě)入的時(shí)候打開(kāi)然后寫(xiě)入,這肯定不是明智的做法,如果有更好的辦法,請(qǐng)留言我
也就是說(shuō),文件打開(kāi)后傳入,是無(wú)效的,那么可以將文件名傳入,然后在run方法中每次寫(xiě)的時(shí)候先打開(kāi),寫(xiě)入后關(guān)閉應(yīng)該也是可行的。
但是為什么我文章采用的第一種方式,也是文件打開(kāi)后傳入,卻是可行的。
以上這篇對(duì)Python的多進(jìn)程鎖的使用方法詳解就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
八個(gè)超級(jí)好用的Python自動(dòng)化腳本(小結(jié))
每天你都可能會(huì)執(zhí)行許多重復(fù)的任務(wù),例如閱讀新聞、發(fā)郵件、查看天氣、打開(kāi)書(shū)簽、清理文件夾等等,本文主要介紹了Python自動(dòng)化腳本,具有一定的參考價(jià)值,感興趣的可以了解一下2022-07-07python庫(kù)umap有效地揭示高維數(shù)據(jù)的結(jié)構(gòu)和模式初探
這篇文章主要介紹了python庫(kù)umap有效地揭示高維數(shù)據(jù)的結(jié)構(gòu)和模式初探,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Python3里的super()和__class__使用介紹
這篇文章主要介紹了Python3里的super()和__class__使用介紹,本文用實(shí)例講解了這兩個(gè)方法之間的關(guān)系,需要的朋友可以參考下2015-04-04python3.4用循環(huán)往mysql5.7中寫(xiě)數(shù)據(jù)并輸出的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇python3.4用循環(huán)往mysql5.7中寫(xiě)數(shù)據(jù)并輸出的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06jupyter lab無(wú)法導(dǎo)入graphviz模塊方式
今天小編就為大家分享一篇jupyter lab無(wú)法導(dǎo)入graphviz模塊方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-02-02PyTorch的深度學(xué)習(xí)入門之PyTorch安裝和配置
這篇文章主要介紹了PyTorch的深度學(xué)習(xí)入門之PyTorch安裝和配置,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-06-06Python?pandas中apply函數(shù)簡(jiǎn)介以及用法詳解
apply()函數(shù)是pandas里面所有函數(shù)中自由度最高的函數(shù), apply()函數(shù)的參數(shù)是一個(gè)函數(shù)指針,這里可以使用lambda表達(dá)式幫助簡(jiǎn)化代碼,下面這篇文章主要給大家介紹了關(guān)于Python?pandas中apply函數(shù)簡(jiǎn)介以及用法的相關(guān)資料,需要的朋友可以參考下2022-09-09Python多進(jìn)程編程技術(shù)實(shí)例分析
這篇文章主要介紹了Python多進(jìn)程編程技術(shù),包括了線程、隊(duì)列、同步等概念及相關(guān)的技巧總結(jié),需要的朋友可以參考下2014-09-09Python 如何實(shí)時(shí)向文件寫(xiě)入數(shù)據(jù)(附代碼)
這篇文章主要介紹了Python 如何實(shí)時(shí)向文件寫(xiě)入數(shù)據(jù)(附代碼),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07