使用多个进程在Python中写入文件

时间:2015-11-12 03:14:20

标签: python multithreading locking multiprocessing critical-section

我一直在探索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()

我怀疑是这个。这里的“开放”调用是阻塞还是已经受到保护,还是我需要实现对“write_to_file”调用的锁定?从本质上讲,当一个进程被另一个进程写入时,是否会打开一个“open”调用块?

1 个答案:

答案 0 :(得分:1)

虽然可以协调多个进程的写入到同时在它们之间打开的文件,通过锁定,可能需要范围锁定,可能需要 fsync()寻求() ...虽然这在大多数操作系统和某些条件下都是可行的......它也可能容易出错,不可靠,并且受到一些奇怪的极端情况的影响(特别是对于通过网络共享的文件而言)作为NFS或SMB)。

我建议这是使用 multiprocessing.Queue 类的完美案例。在进程中充当消费者,写入文件,让所有其他人充当生产者写入队列而不是文件。这可能会超越你试图为自己拼凑的任何锁定策略,而且几乎可以肯定会更强大。