共享文件写入的交错输出

时间:2017-04-20 14:43:19

标签: python

我有一个长期运行的python程序在共享文件上执行“追加”写入(多进程):

out = open("shared_file", "a")
while has_input:
     do_processing()
     out.write("%s, %s, %s\n" % field1, field2, field3)

上面的伪代码是用8个进程运行的。这将导致一小部分交错输出。这似乎与缓冲区相关,基于谷歌搜索。做共享文件追加的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

  

问题:进行共享文件追加的正确方法是什么?

  1. 使用一个编写器Process,仅将数据写入/追加到文件中。

  2. 与其他流程共享工作量。

  3. 使用Queue传递数据以从工作负载进程附加到编写器进程。

  4. 阅读本文答案:python-multiprocessing-write-to-same-excel-file

答案 1 :(得分:1)

fcntl module有与此相关的助手。如果要将整个写入块(while has_input:)放在一起,可以使用以下命令:

with out = open("shared_file", "a"):
    fcntl.flock(out, fcntl.LOCK_EX)
    try:
        while has_input:
            out.write("%s, %s, %s\n" % (field1, field2, field3))
    finally:
        fcntl.flock(out, fcntl.LOCK_UN)

相比之下,如果您只关心将各个行保持在一起,并且不介意一些额外的开销,那么可以使用更精细的锁定:

with out = open("shared_file", "a"):
    while has_input:
        try:
            fcntl.flock(out, fcntl.LOCK_EX)
            out.write("%s, %s, %s\n" % (field1, field2, field3))
        finally:
            fcntl.flock(out, fcntl.LOCK_UN)

也就是说,如果你的目标只是阻止一行来自两个不同进程的内容,并用O_APPEND打开你的文件,那么操作系统级语义通常在保持个人写入方面相当有效原子。原子性可以 break 的一种方法是缓冲,但是你可以通过在没有缓冲区的情况下打开文件来避免这种影响,这样就可以立即刷新所有写入:

out = open("shared_file", "a", 0)