Python多进程如何写入共享文件?

7
当我向一个已经通过将其传递给使用多进程实现的工作函数而共享的打开文件写入时,文件内容没有正确地被写入。相反,'^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^'被写入到文件中。
为什么会发生这种情况?你不能让许多多处理单元写入同一个文件吗?你需要使用锁吗?队列?我是否没有正确或有效地使用多进程?
我觉得一些示例代码可能会有所帮助,但请只将其作为我打开文件并通过多进程传递打开文件到另一个进行写入的函数的参考。
多进程文件:
import multiprocessing as mp

class PrepWorker():
    def worker(self, open_file):
        for i in range(1,1000000):
            data = GetDataAboutI() # This function would be in a separate file
            open_file.write(data)
            open_file.flush()
        return

if __name__ == '__main__':
    open_file = open('/data/test.csv', 'w+')
    for i in range(4):
        p = mp.Process(target=PrepWorker().worker, args=(open_file,))
        jobs.append(p)
        p.start()

    for j in jobs:
        j.join()
        print '{0}.exitcode = {1}' .format(j.name, j.exitcode)   
    open_file.close()

这些代码示例中可能有一些不必要的细节。[MCVE] - ivan_pozdeev
^@”是从哪里来的?我在代码中找不到类似的东西。这些是文字还是控制符号的表示? - ivan_pozdeev
@ccdpowell,但你可以查看十六进制文件来回答第二个问题。 - ivan_pozdeev
1
根据@user的问题,我运行了随机字符串,并能够更清楚地解决问题。每个^@都是在除最后一个进程外的每个进程应该写入字符的位置上写入的。例如,如果我使用4个处理器运行此示例,每个处理10个项目,则会得到一个由30个'^@'和10个可读字符组成的字符串。 - ccdpowell
你看过https://dev59.com/-GMl5IYBdhLWcg3wbGd1吗? - serv-inc
显示剩余5条评论
1个回答

5
为什么会发生这种情况?
有几个进程可能会尝试调用。
open_file.write(data)
open_file.flush()

同时进行以下操作,你认为哪种行为更合适?

  • a.write
  • b.write
  • a.flush
  • c.write
  • b.flush

许多个多进程单元是否可以写入同一个文件?需要使用锁定吗?队列?

Python多进程安全地写入文件 建议使用一个队列,由一个进程读取并将内容写入文件。 使用多进程写入文件在Python中处理多个进程的单个文件 也是如此。


3
谢谢。这正是我需要的。我试图对数据进行过多的处理,进程之间会有重叠,写入和刷新之间也会有冲突。这个问题源于对如何构建多进程作业的基本理解不足。 - ccdpowell
1
为什么使用锁来防止不同进程交错写入/刷新不起作用?我使用此处描述的方法分发计数器,并发现同样的方法对于打开的文件也适用。http://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessing - ccdpowell
@ccdpowell:你链接的网站代码看起来没问题。不过如果没有看到你的代码,很难说。你可以用修改后的代码提一个新问题吗?(如果没有立即回答,请随时提醒我) - serv-inc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接