【问题标题】:Python: is it ok to call subprocess.Popen in a thread?Python:可以在线程中调用 subprocess.Popen 吗?
【发布时间】:2020-10-02 11:26:34
【问题描述】:

请注意,此问题Python Subprocess.Popen from a thread 相同,因为该问题并未寻求解释为什么可以。

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

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

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

这个问题适用于其他线程分叉程序,而不仅仅是 Python。

【问题讨论】:

    标签: python multithreading subprocess python-multiprocessing


    【解决方案1】:

    Forking only results in the calling thread being active in the fork, not all threads.。大多数与多线程程序中的分叉相关的陷阱都与其他线程持有的互斥锁有关,这些线程永远不会在分叉中释放。当您使用 Popen 时,一旦您execv,您将启动一些不相关的进程,所以这不是一个真正的问题。 Popen 文档中有一条警告要小心使用多个线程和 preexec_fn 参数,该参数在 execv 调用发生之前运行:

    警告 preexec_fn 参数在存在以下情况时使用不安全 应用程序中的线程。子进程之前可能会死锁 exec 被调用。如果您必须使用它,请保持微不足道!最小化 您调用的库数。

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

    【讨论】:

    • 哇,谢谢!它把我带到了 POSIX 2018 规范:“一个进程应该用一个线程创建。如果一个多线程进程调用 fork(),新进程应该包含调用线程的副本及其整个地址空间,可能包括互斥锁和其他资源的状态。” (pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html) 也可以将此添加到您的答案中,以使未来的读者受益。
    猜你喜欢
    • 2019-08-19
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 2018-05-12
    • 2011-09-16
    相关资源
    最近更新 更多