如果创建multiprocessing.Pool,则Python子进程wait()失败

克里斯托弗·施密特(Christopher Schmidt)

在一个简单的脚本中,该脚本使用子进程gzip输出(使用subprocess.PIPE到外部命令的stdin),如果在创建子进程和关闭进程的stdin之间创建了multiprocessing.Pool对象,则subprocess.wait ()将永远挂起。

import multiprocessing
import subprocess

proc = subprocess.Popen(["gzip", "-c", "-"], 
                        stdout=open('filename', 'w'), stdin=subprocess.PIPE)
multiprocessing.Pool()
proc.stdin.close()
proc.wait()

移动多重处理池向上或向下一行调用可避免此问题。

我在Python 2.7.3(Linux)和Python 2.7.1(OS X)上遇到了这个问题。

显然,这是一个简单的例子-实际用法要复杂得多。我也已经知道GzipFile了-我宁愿不使用它;通过使用子进程,我可以通过将gzip拆分为一个单独的线程来获得更多的CPU使用率。

我看不到如何简单地实例化Pool应该会产生这种影响。

周二

调用时multiprocessing.Poolmultiprocessing模块将创建几个新进程(使用os.fork或类似的进程)。

默认情况下,在期间fork,新进程将继承所有打开的文件描述符。

当您subprocess.Popen使用subprocess.PIPE参数调用subprocess模块将创建一些新的管道文件描述符,以向/从新进程发送数据。在这种特殊情况下,管道用于将数据从父进程(python)发送到子进程(gzip),并且proc.wait()对管道的所有写访问都消失,gzip将退出并完成操作(这就是在管道上生成“ EOF”的原因:该管道不再存在可写文件描述符。)

因此,在这种情况下,如果您(全部在“原始” python进程中)按以下顺序执行此操作:

  1. 创建管道
  2. 创建一些multiprocessing.Pool流程
  3. 发送数据到gzip
  4. 关闭管道以gzip

然后,由于的行为fork,每个Pool进程都有一个os.dupwrite-to-gzip管道,因此gzip继续等待更多的数据,这些Pool进程可以(但从不发送)发送。一旦Pool进程关闭其管道描述符,gzip进程将退出。

用实际的(更复杂的)代码解决这个问题可能并不容易。理想情况下,您想multiprocessing.Pool知道的是(魔术地以某种方式)应该保留哪些文件描述符,而不应该保留哪些文件描述符,但这并不像“仅在创建的子进程中关闭一堆描述符”那样简单:

output = open('somefile', 'a')
def somefunc(arg):
    ... do some computation, etc ...
    output.write(result)
pool = multiprocessing.Pool()
pool.map(somefunc, iterable)

显然output.fileno(),这里的工作进程必须共享。

你可以尝试使用Poolinitializer调用proc.stdin.close(或os.closeFD的名单上),但你需要安排跟踪描述为闭合的。重组代码以避免“在错误的时间”创建池可能是最简单的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如果失败则如何退出python子进程

来自分类Dev

python multiprocessing动态创建的进程和管道

来自分类Dev

如果创建,Python子进程stderr / stdout字段为None

来自分类Dev

Python何时创建子进程?

来自分类Dev

Python何时创建子进程?

来自分类Dev

python multiprocessing,为每个进程创建实例并重用它

来自分类Dev

python multiprocessing-子进程阻止父进程

来自分类Dev

如果从Python运行进程,则getaddrinfow失败

来自分类Dev

Python multiprocessing.Process对象与multiprocessing.Manager在Windows Task Manager中创建多个multiprocessing派生

来自分类Dev

设置maxtasksperchild时,Python multiprocessing.Pool失败

来自分类Dev

提前退出multiprocessing.Pool.map(在子进程中进行提升不起作用)

来自分类Dev

创建 python 循环作为“分离的”子进程

来自分类Dev

使用python multiprocessing子进程如何终止另一个子进程?

来自分类Dev

python multiprocessing子进程触发父事件或方法

来自分类Dev

如何区分Multiprocessing.Pool中的进程?

来自分类Dev

如何在Python中使用multiprocessing.pool创建全局锁/信号灯?

来自分类Dev

python,multiprocessing和dmtcp:在Pool中检查一个进程?

来自分类Dev

列表长于进程数时的Python multiprocessing.Pool.map行为

来自分类Dev

python multiprocessing.pool.map,将参数传递给生成的进程

来自分类Dev

如果父项在Python中被杀死,则杀死子进程

来自分类Dev

如果不使用子进程,如何使用python读取stderr?

来自分类Dev

如果绕过列表包含“ *”,则创建代理失败

来自分类Dev

如果ping失败,MacOS会创建通知?

来自分类Dev

创建子对象(如果不存在)

来自分类Dev

在Unix中创建子进程的子进程

来自分类Dev

获取子节点(如果存在),否则在Python中创建

来自分类Dev

Python Multiprocessing-进程数

来自分类Dev

杀死在Python的__init__类中创建的子进程

来自分类Dev

杀死在Python的__init__类中创建的子进程

Related 相关文章

  1. 1

    如果失败则如何退出python子进程

  2. 2

    python multiprocessing动态创建的进程和管道

  3. 3

    如果创建,Python子进程stderr / stdout字段为None

  4. 4

    Python何时创建子进程?

  5. 5

    Python何时创建子进程?

  6. 6

    python multiprocessing,为每个进程创建实例并重用它

  7. 7

    python multiprocessing-子进程阻止父进程

  8. 8

    如果从Python运行进程,则getaddrinfow失败

  9. 9

    Python multiprocessing.Process对象与multiprocessing.Manager在Windows Task Manager中创建多个multiprocessing派生

  10. 10

    设置maxtasksperchild时,Python multiprocessing.Pool失败

  11. 11

    提前退出multiprocessing.Pool.map(在子进程中进行提升不起作用)

  12. 12

    创建 python 循环作为“分离的”子进程

  13. 13

    使用python multiprocessing子进程如何终止另一个子进程?

  14. 14

    python multiprocessing子进程触发父事件或方法

  15. 15

    如何区分Multiprocessing.Pool中的进程?

  16. 16

    如何在Python中使用multiprocessing.pool创建全局锁/信号灯?

  17. 17

    python,multiprocessing和dmtcp:在Pool中检查一个进程?

  18. 18

    列表长于进程数时的Python multiprocessing.Pool.map行为

  19. 19

    python multiprocessing.pool.map,将参数传递给生成的进程

  20. 20

    如果父项在Python中被杀死,则杀死子进程

  21. 21

    如果不使用子进程,如何使用python读取stderr?

  22. 22

    如果绕过列表包含“ *”,则创建代理失败

  23. 23

    如果ping失败,MacOS会创建通知?

  24. 24

    创建子对象(如果不存在)

  25. 25

    在Unix中创建子进程的子进程

  26. 26

    获取子节点(如果存在),否则在Python中创建

  27. 27

    Python Multiprocessing-进程数

  28. 28

    杀死在Python的__init__类中创建的子进程

  29. 29

    杀死在Python的__init__类中创建的子进程

热门标签

归档