Python 下多进程的问题

2017-04-15 14:08:14 +08:00
 tianshilei1992

问题背景

现在有一个 Python 程序,这个程序里面 import abc 模块,该是用 C++ 编写的,编写的时候还使用了 OpenMP 多线程库。直接通过 python xxx.py --options OPTIONS 来运行,可以感受到多线程带来性能上的提升。但是这个 abc 模块的编写似乎有一点问题,在某些参数条件下会崩溃,这个崩溃不是抛出异常,而是整个 Python 程序(解释器)的崩溃,没有任何错误提示。OPTIONS 最终也是由 __main__ 函数负责解析,调用里面的函数 func(args...) 来完成。

我们需要测试不同的参数组合,并且不想因为某一组参数导致整个测试程序的崩溃。所以我们就另外编写了一个 Python 程序,里面 from xxx import func,然后想要通过派生一个新的进程来执行 func,防止因为崩溃导致主进程的崩溃。

multiprocessing 方式

首先想到的是使用 multiprocessing 方式,相关的代码如下:

from multiprocessing import Process
from xxx import func

p = Process(target=func, args=(__OPTIONS__)) # __OPTIONS__ 为想要传入的参数
p.start()
p.join(300) # 设置主进程阻塞 300 秒
while p.is_alive():
  p.terminate()
# 处理 IPC 回收数据

设定超过 300 秒就算失败。现在的问题是,使用这种方式执行 func 后,看起来 func 的执行失去了并行能力,执行其中的一个运算会卡住,但是这个卡住是真卡住了还是因为没有运算完,这个无从得知。

subprocess 方式

其次想到的就是利用 subprocess 来做,相关代码如下:

import subprocess
from xxx import func

p = subprocess.Popen('python xxx.py --options OPTIONS', shell=True)
# 处理超时以及从 STDOUT 回收数据

利用这种方式 xxx.py 可以正常的并行执行,但是想要回收数据,只能通过 STDOUT 或者写入文件来进行。

问题

为什么通过 multiprocess.Process 执行的函数多进程会看起来丧失并行能力?

2999 次点击
所在节点    Python
10 条回复
rogerchen
2017-04-15 14:29:44 +08:00
子进程在的 python 解释器都挂了还能指望 join 能正常工作么?
pagxir
2017-04-15 14:36:48 +08:00
你明显不会写异步处理的程序。
gouchaoer
2017-04-15 14:44:47 +08:00
用 exec 调用来?
gouchaoer
2017-04-15 14:46:17 +08:00
py 下没试过。。。。 php 下用异步的类 exec 调用可以开 n 个 php 程序,具体 api 是 proc_open 。。。。 py 下肯定有这样的 api
tianshilei1992
2017-04-15 15:00:40 +08:00
@rogerchen 通过 spawn 方式的 Process 不是重新开一个新的 Python 解释器来做吗?不过似乎 Python 2 不支持这种定义?
tianshilei1992
2017-04-15 15:01:06 +08:00
@pagxir 没有经验,希望多多指教。
tianshilei1992
2017-04-15 15:04:30 +08:00
@gouchaoer 查到 Python 下可以用 pool.apply_async 似乎是同样的工作,周一去试试。
其实我就想让主进程调用完了就阻塞的。
yucongo
2017-04-15 15:37:55 +08:00
试试
p.daemon = True
p.start()
wwqgtxx
2017-04-15 16:10:23 +08:00
如果你自己看过 multiprocess.Process 的源代码,他内部是有子进程和父进程的通讯的,而你的子程序可能因为某些原因导致了通讯未能正常进行,所以就表选出卡住了的状态,而一个正常运行的 python 解析器是肯定可以保证通讯正常进行的
另外,实际上 multiprocess.Process 内部依然使用了 Popen 来实现,所以你自己模仿实现一个也没啥毛病
tianshilei1992
2017-04-16 08:10:39 +08:00
@wwqgtxx 好的 谢谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/355066

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX