2

我一直在探索python中的多處理器編程,以及它與多線程之間的差異,以及我對寫入文件的疑問。所以下面是我發現的,對於下面的代碼,沒有任何東西被寫入到文件中,我認爲這是因爲打開的文件處理程序不是跨進程共享的。使用多進程在Python中寫入文件

import multiprocessing 
import sys 
import datetime 
import time 


def worker(fd, index): 
    fd.write("worker %d %s\n" % (index, datetime.datetime.now())) 
    time.sleep(5 - index) 
    fd.write("worker %d again %s\n" % (index, datetime.datetime.now())) 

if __name__ == '__main__': 
    fd = open(sys.argv[1], "w") 
    threads = list() 
    for i in xrange(5): 
    th = multiprocessing.Process(target=worker, args=(fd, i,)) 
    threads.append(th) 
    th.start() 

    for each in threads: 
    each.join() 

    fd.close() 

而下面的代碼由於線程之間的共享內存正常工作。

import threading 
import sys 
import datetime 


def worker(fd, index): 
    fd.write("worker %d %s\n" % (index, datetime.datetime.now())) 
    time.sleep(5 - index) 
    fd.write("worker %d again %s\n" % (index, datetime.datetime.now())) 

if __name__ == '__main__': 
    fd = open(sys.argv[1], "w") 
    threads = list() 
    for i in xrange(5): 
    th = threading.Thread(target=worker, args=(fd, i,)) 
    threads.append(th) 
    th.start() 

    for each in threads: 
    each.join() 

    fd.close() 

我想用多進程而不是線程寫入同一個文件,所以我實現了以下功能。我認爲我可能不得不使用鎖來限制不同進程對文件的訪問,但是如果沒有它,下面的工作似乎可以正常工作。

import multiprocessing 
import sys 
import datetime 
import time 


def write_to_file(text, file_name): 
    fd = open(file_name, "a") 
    fd.write(text) 
    fd.close() 


def worker(file_name, index): 
    while True: 
    write_to_file("worker %d %s\n" % (index, datetime.datetime.now()), file_name) 
    time.sleep(5 - index) 
    write_to_file("worker %d %s again\n" % (index, datetime.datetime.now()), file_name) 


if __name__ == '__main__': 
    file_name = sys.argv[1] 
    fd = open(file_name, 'w') 
    fd.write("test input\n") 
    fd.close() 
    jobs = [] 
    for i in xrange(5): 
    process = multiprocessing.Process(target=worker, args=(file_name, i,)) 
    process.start() 
    jobs.append(process) 

    for j in jobs: 
    j.join() 

我的疑問是圍繞着這個。這裏的「open」調用是否被阻塞並且已經受到保護,還是我需要實現對「write_to_file」調用的鎖定?從本質上講,當文件被另一個進程寫入時,一個進程的「open」調用會阻塞嗎?

回答

1

雖然可以統籌從多個進程寫入被同時它們之間打開時,通過鎖定,可能將會導致鎖定範圍,可能將會導致FSYNC(文件)尋求() ...儘管在大多數操作系統和某些條件下這是可能的......但它也可能容易出錯,不可靠,並受到一些奇怪的角落案例的影響(特別是對於通過網絡共享的文件,例如NFS或SMB)。

我認爲,這是使用multiprocessing.Queue類一個完美的案例。讓流程充當消費者,寫入文件,讓所有其他人充當生產者寫入隊列而不是寫入文件。這可能會超越任何你試圖爲自己拼湊起來的鎖定策略,而且幾乎肯定會更加強大。