Python 多进程向同一个文件写数据
1.遇到的問(wèn)題:
之前,因?yàn)榭紤]到Python多進(jìn)程可以充分利用CPU核數(shù),提高程序的效率,所以就使用多進(jìn)程寫文件。但是向同一個(gè)文件寫入數(shù)據(jù)的時(shí)候,由于多進(jìn)程是并發(fā)進(jìn)行,操作系統(tǒng)中會(huì)不清楚到底要寫入哪個(gè)數(shù)據(jù)到文件中,所以會(huì)出現(xiàn)資源競(jìng)爭(zhēng)混亂,導(dǎo)致文件內(nèi)容輪亂。
不過(guò)你還可以給文件加鎖,但是加鎖一般會(huì)造成程序的執(zhí)行速度下降,而且如果進(jìn)程在多處需要向文件輸出,也不好把這些代碼整個(gè)都鎖起來(lái),如果都鎖起來(lái),那跟單進(jìn)程還有什么區(qū)別。
2.解決思路如下:
跟把文件輸出集中在一起也差不多,就是把進(jìn)程需要寫入文件的內(nèi)容作為返回值返回給回調(diào)函數(shù),使用回調(diào)函數(shù)向文件中寫入內(nèi)容。不過(guò)還有一種更加優(yōu)雅的解決方式:使用multiprocessing庫(kù)的回調(diào)函數(shù)功能。
3.應(yīng)用場(chǎng)景:
進(jìn)程池中任何一個(gè)任務(wù)一旦處理完了,就立即告知主進(jìn)程:我好了,你可以處理我的結(jié)果了。主進(jìn)程則調(diào)用一個(gè)函數(shù)去處理該結(jié)果,該函數(shù)即回調(diào)函數(shù)。我們可以把耗時(shí)間(阻塞)的任務(wù)放到進(jìn)程池中,然后指定回調(diào)函數(shù)(主進(jìn)程負(fù)責(zé)執(zhí)行),這樣主進(jìn)程在執(zhí)行回調(diào)函數(shù)時(shí)就省去了I/O的過(guò)程,直接拿到的是任務(wù)的結(jié)果。
4.異步回調(diào)函數(shù) apply_async
源代碼如下,有興趣可以看看:
def apply_async(self, func, args=(), kwds={}, callback=None,error_callback=None):'''Asynchronous version of `apply()` method.'''if self._state != RUN:raise ValueError("Pool not running")result = ApplyResult(self._cache, callback, error_callback)self._taskqueue.put(([(result._job, 0, func, args, kwds)], None))return result參數(shù)解釋下:
- func 是調(diào)用的函數(shù)
- args 是給指定的函數(shù)傳遞的參數(shù),以元組的方式傳遞
- kwargs:傳遞字典類型參數(shù)
- callback:只能接受單個(gè)參數(shù)的可調(diào)用對(duì)象,當(dāng)結(jié)果完成時(shí)就找對(duì)象的callback回調(diào)函數(shù)
- error_callback:只能一個(gè)接受單個(gè)參數(shù)的可調(diào)用對(duì)象。如果目標(biāo)函數(shù)失敗,則以該異常實(shí)例調(diào)用error_callback。
代碼示例:
import multiprocessing# 設(shè)置回調(diào)函數(shù) def setcallback(x):with open('result.txt', 'a+') as f:line = str(x) + "\n"f.write(line)def multiplication(num):return num*(num+1)if __name__ == '__main__':pool = multiprocessing.Pool(6)for i in range(1000):pool.apply_async(func=multiplication, args=(i,), callback=setcallback)pool.close()pool.join()這是保存完畢的文件,部分內(nèi)容,可以看出數(shù)據(jù)沒(méi)有混亂。
總結(jié):
apply_async是異步非阻塞式,不用等待當(dāng)前進(jìn)程執(zhí)行完畢,隨時(shí)跟進(jìn)操作系統(tǒng)調(diào)度來(lái)進(jìn)行進(jìn)程切換,即多個(gè)進(jìn)程并行執(zhí)行,提高程序的執(zhí)行效率。回調(diào)應(yīng)該立即完成,否則處理結(jié)果的線程將被阻塞。
總結(jié)
以上是生活随笔為你收集整理的Python 多进程向同一个文件写数据的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python random模块的使用
- 下一篇: python对excel表格操作