请注意,该问题与Python Subprocess.Popen from a thread 不同,因为该问题并未寻求对它为什么可以解决的解释。
如果我理解正确,subprocess.Popen()
将通过分叉当前进程并执行新程序来创建一个新进程。
但是,如果当前进程是多线程的,并且我们在其中一个线程中调用subprocess.Popen()
,那么它是否会复制当前进程中的所有线程(因为它调用syscall fork()
) ?如果是这样的话,尽管在系统调用execv
之后这些重复的线程将被清除,但是在一定的时间间隔内重复的线程可以做很多令人讨厌的事情。
一个恰当的例子是gtest_parallel.py,其中程序在execute_tasks()
中创建了一堆线程,并且在每个线程中task_manager.run_task(task)
将调用task.run()
,后者将调用{{ 1}}来运行任务。可以吗?
这个问题适用于其他派生线程程序,而不仅仅是Python。
答案 0 :(得分:0)
Forking only results in the calling thread being active in the fork, not all threads.。与多线程程序中的分叉有关的大多数陷阱都与其他线程持有的互斥量有关,这些互斥量永远不会在fork中释放。使用Popen时,execv
一旦启动,您将启动一些无关的过程,因此这并不是真正的问题。 Popen
文档中有一个警告,提示谨慎使用多个线程和preexec_fn
参数,该参数在execv调用发生之前运行:
警告如果存在以下情况,则
preexec_fn
参数不安全使用 您的应用程序中的线程。子进程可能在之前陷入僵局 exec被调用。如果您必须使用它,请保持琐碎!最小化 您调用的库的数量。
至少在最新版本的Python中,我不知道需要使用Popen
来注意的其他陷阱。 Python 2.7's subprocess
module does seem to have flaws that can cause issues with multi-threaded applications, however.