Python: 在线程中调用 subprocess.Popen 可以吗?

Python: is it ok to call subprocess.Popen in a thread?

Note this question is not the same as Python Subprocess.Popen from a thread, because that question didn't seek an explanation on why it is ok.

如果我理解正确,subprocess.Popen() 通过分叉当前进程并执行新程序来创建一个新进程。

但是,如果当前进程是多线程的,我们在其中一个线程中调用subprocess.Popen(),会不会复制了当前进程中的所有线程(因为它调用了syscall fork())?如果是这样的话,虽然这些重复的线程会在系统调用后被清除 execv,但有一个时间间隔,重复的线程可以做一堆讨厌的事情。

一个典型的例子是gtest_parallel.py,其中程序在execute_tasks()中创建了一堆线程,并且在每个线程中task_manager.run_task(task)会调用task.run(),它调用subprocess.Popen() 到 运行 一个任务。可以吗?

The question applies to other fork-in-thread programs, not just Python.

Forking only results in the calling thread being active in the fork, not all threads.. Most of the pitfalls related to forking in a multi-threaded program are related to mutexes being held by other threads that will never be released in the fork. When you're using Popen, you're going to launch some unrelated process once you execv, so that's not really a concern. There is a warning in the Popen docs about being careful with multiple threads and the preexec_fn 参数,在 execv 调用发生之前运行:

Warning The preexec_fn parameter is not safe to use in the presence of threads in your application. The child process could deadlock before exec is called. If you must use it, keep it trivial! Minimize the number of libraries you call into.

我不知道 Popen 有任何其他需要注意的陷阱,至少在 Python 的最新版本中是这样。 Python 2.7's subprocess module does seem to have flaws that can cause issues with multi-threaded applications, however.