Python並發寫入一個文件


今天就為大家分享一篇Python多進程寫入同一文件的方法,具有很好的參考價值,希望對大家有所幫助。

最近用python的正則表達式處理了一些文本數據,需要把結果寫到文件里面,但是由於文件比較大,所以運行起來花費的時間很長。但是打開任務管理器發現CPU只占用了25%,上網找了一下原因發現是由於一個叫GIL的存在,使得Python在同一時間只能運行一個線程,所以只占用了一個CPU,由於我的電腦是4核的,所以CPU利用率就是25%了。

既然多線程沒有什么用處,那就可以使用多進程來處理,畢竟多進程是可以不受GIL影響的。Python提供了一個multiprocessing的多進程庫,但是多進程也有一些問題,比如,如果進程都需要寫入同一個文件,那么就會出現多個進程爭用資源的問題,如果不解決,那就會使文件的內容順序雜亂。這就需要涉及到鎖了,但是加鎖一般會造成程序的執行速度下降,而且如果進程在多處需要向文件輸出,也不好把這些代碼整個都鎖起來,如果都鎖起來,那跟單進程還有什么區別。有一個解決辦法就是把向文件的輸出都整合到一塊去,在這一塊集中加個鎖,這樣問題就不大了。不過還有一種更加優雅的解決方式:使用multiprocessing庫的回調函數功能。

具體思路跟把文件輸出集中在一起也差不多,就是把進程需要寫入文件的內容作為返回值返回給惠和的回調函數,使用回調函數向文件中寫入內容。這樣做在windows下面還有一個好處,在windows環境下,python的多進程沒有像linux環境下的多進程一樣,linux環境下的multiprocessing庫是基於fork函數,父進程fork了一個子進程之后會把自己的資源,比如文件句柄都傳遞給子進程。但是在windows環境下沒有fork函數,所以如果你在父進程里打開了一個文件,在子進程中寫入,會出現ValueError: I/O operation on closed file這樣的錯誤,而且在windows環境下最好加入if __name__ == '__main__'這樣的判斷,以避免一些可能出現的RuntimeError或者死鎖。

下面是代碼:

from multiprocessing import Pool
import time


def mycallback(x):
  with open('123.txt', 'a+') as f:
    f.writelines(str(x))


def sayHi(num):
  return num


if __name__ == '__main__':
  e1 = time.time()
  pool = Pool()

  for i in range(10):
    pool.apply_async(sayHi, (i,), callback=mycallback)

  pool.close()
  pool.join()
  e2 = time.time()
  print float(e2 - e1)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM