如何在多个子进程之间共享一个输出tarfile?

时间:2019-04-13 11:22:56

标签: python-3.x python-multiprocessing fcntl tarfile

我正在开发一个备份脚本,该脚本利用python的multiprocessing模块在​​多个子进程之间共享其工作。在大多数情况下,这是一个相对简单的过程。在一段时间前的测试条件下,我发现,如果执行以下操作,与单进程处理相比,速度可以提高约20%: 1.将要添加到输出tarfile的文件划分为各个任务,并且; 2.让等于该计算机的cpu-core数量的工人(在我的示例中为4个)将这些工作分配给他们。

我最初是在Linux下使用mp.Lock()对象实现此功能的,这些对象在运行时被扔到与子进程争用的字典中。出于明显的原因,这在Windows中不起作用(由于进程创建spawn()方法的限制),所以从那时起,我一直尝试:

  • 实施管理者流程(似乎无法正确地分享给孩子们)
  • 包括mp.Lock()对象作为任务而不是进程的参数(无法完成,python仅通过继承接受子代中的锁)
  • 完全放弃Lock原语,使用msvcrtfcntl来实现FS / OS级文件锁定。

当我使用fcnt.lockf()进行此操作时,我可以正确获取锁,但是子进程无法将其输出写入文件,即使它认为确实如此(例如,不会引发异常) )。我对fcntl的实现如下:

import fcntl
                print("Gonna open %s" % self.tarf)
                #try:
                file = open(self.tarf, "a+b")
                file.seek(0)
                print("Can I lock?")
                fcntl.lockf(file, fcntl.LOCK_SH)
                print("got the lock")
                tar = tarfile.open(fileobj=file, mode="a:")
                print("tarfile opened")
                info = tar.gettarinfo(self.b, self.a)
                with open(self.b, "rb") as fd:
                    tar.addfile(info, fd)
                print("file inserted: %s" % self.a)
                tar.close()
                fcntl.lockf(file, fcntl.LOCK_UN)
                file.close()
                waiting = False

我的问题有两个:

  • 有没有使用mp.Lock()对象的正确方法?
  • 是否存在在Windows中使用管理器的特殊技巧,而在创建时就没有将管理器的代理对象(例如dict_locks = manager.dict())争论到子进程中了?

我在堆栈溢出方面不是很擅长,因此,如果我能提供其他信息,请告诉我。我对上面提供的代码片段的期望是,通过在给定的子进程中获取fcntl锁,将锁定的文件对象移交给tarfile.open,并使用tarfile.addfile添加文件(我也尝试了使用相同结果的普通tarfile.add ),然后关闭/解锁文件即可。我怀疑有关文件锁定的某些内容正在默默地阻止tarfile.add操作,因为运行该代码的孩子可以告诉孩子,文件已成功添加。没有异常,但是当我拉出tarfile并检查它时-nada。

0 个答案:

没有答案