请注意,这个问题与线程中的Python Subprocess.Popen不同,因为该问题没有寻求解释为什么它可以。
如果我理解正确,subprocess.Popen()
通过分叉当前进程和执行新程序来创建一个新进程。
但是,如果当前进程是多线程的,并且我们在其中一个线程中调用subprocess.Popen()
,它不会复制当前进程中的所有线程(因为它调用 syscallfork()
(?如果是这样的话,虽然这些重复的线程将在系统调用execv
后被清除,但有一个时间间隔,重复的线程可以做一堆讨厌的事情。
一个典型的例子是gtest_parallel.py,程序在execute_tasks()
中创建一堆线程,并在每个task_manager.run_task(task)
线程中调用task.run()
,调用subprocess.Popen()
来运行任务。可以吗?
这个问题适用于其他线程中的分支程序,而不仅仅是Python。
分叉只会导致调用线程在分叉中处于活动状态,而不是所有线程。与多线程程序中的分叉相关的大多数陷阱都与互斥体由其他线程持有有关,这些线程永远不会在分叉中释放。当你使用Popen时,一旦你execv
,你就会启动一些不相关的进程,所以这不是一个真正的问题。Popen
文档中有一个警告,关于小心处理多个线程和preexec_fn
参数,该参数在 execv 调用发生之前运行:
警告
preexec_fn
参数在存在以下情况下使用不安全 应用程序中的线程。子进程可能会在之前死锁 调用执行。如果您必须使用它,请保持琐碎!最小化 您调用的库数。
我不知道Popen
还有什么其他需要注意的陷阱,至少在最新版本的 Python 中是这样。但是,Python 2.7 的subprocess
模块似乎确实存在可能导致多线程应用程序出现问题的缺陷。