请注意,这个问题与Python Subprocess.Popen from a thread not相同,因为该问题并未寻求解释为什么可以。
如果我理解正确,subprocess.Popen()
通过分叉当前进程并执行新程序来创建一个新进程。
但是,如果当前进程是多线程的,并且我们在一个线程中调用了subprocess.Popen()
,那么它是否会复制当前进程中的所有线程(因为它调用了syscall fork()
)?如果是这种情况,尽管在系统调用execv
之后将清除这些重复的线程,但是在一定的时间间隔内重复的线程可以做很多令人讨厌的事情。
一个合适的例子是gtest_parallel.py,程序在execute_tasks()
中创建了一堆线程,并且在每个线程中task_manager.run_task(task)
将调用task.run()
,后者将调用subprocess.Popen()
以运行任务。可以吗?
该问题适用于其他派生线程程序,而不仅仅是Python。
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中,我不知道需要使用preexec_fn
注意的其他陷阱。 Popen