【问题标题】:How to create a suspended subprocess in Python on Windows?如何在 Windows 上的 Python 中创建一个挂起的子进程?
【发布时间】:2022-12-30 10:00:30
【问题描述】:

我想通过 subprocess.Popen 创建一个以挂起状态启动的子进程,这样我就可以准备好在以后运行。

我找到了适用于 Linux here 的解决方案,但找不到适用于 Windows 的任何解决方案。有谁知道是否有与此等效的 Windows?

【问题讨论】:

  • 您的问题归结为 How to suspend/resume a process in Windows,然后是如何从 Python 的 Windows API 调用 SuspendThread,您可以使用 pywin32 来完成。不过这并不容易 - 为什么你首先要这样做?你实际要解决什么问题? “这样我就可以准备好在稍后运行”——为什么不准备启动流程所需的一切,而是在需要时才真正启动流程?
  • 我想在父进程死亡时清理任何孤立的子进程,我认为这在 Popen 中默认情况下不会发生。调查后,我发现 this link 提到使用 Windows JobObjects 来处理孤儿。他们提供了一些示例代码,并提到他们的解决方案存在竞争条件。在那篇文章的 cmets 中,有人提到在将进程附加到 JobObject 之前暂停进程将修复该竞争条件。我宁愿避免竞争条件,但我知道这可能不是最好的解决方案。
  • 正如该答案的作者所说,“如果孩子在 Popen 和 OpenProcess 调用之间死亡,这里有一个微小的竞争条件,你可以决定是否要担心这个”——发生这种情况的可能性微乎其微。如果你担心它,用一个启动器包装子进程,如果它的父进程在它启动之前就死了,它就不会启动,不需要处理挂起的进程。 (当然,所有这些都假设您实际上并没有编写启动的进程,否则它只能检查其父进程本身)
  • 谢谢您的帮助!我认为包装子进程似乎是我最好的选择,因为我没有编写启动的进程。

标签: python windows subprocess


【解决方案1】:

经过更多调查后,我设法创建了一个挂起的进程并在稍后恢复它。谢天谢地,使用 Popen 和 Windows 创建挂起的进程非常简单。

首先,您需要通过运行以下命令来安装 pywin32:

pip install pywin32

安装 pywin32 后,您可以使用 subprocess.Popen 创建一个挂起的进程:

from win32process import CREATE_SUSPENDED
from subprocess import Popen

pipe = subprocess.Popen(<command>, <**kwargs>, creationflags=CREATE_SUSPENDED)

然而,恢复这个挂起的进程要困难得多,因为它需要一个用于挂起线程的 PyHandle。不幸的是,Popen 没有返回为挂起线程打开 PyHandle 所需的线程 ID。作为一种解决方法,我最终对 Popen 的 _execute_child 函数进行了猴子修补,以存储 _winapi.CreateProcess 返回的线程 ID。现在我们有了挂起进程的线程 ID,我们可以恢复线程。

假设您对 Popen 进行了 monkeypatched 以存储线程 ID,要恢复挂起的进程,请使用:

from win32api import OpenThread, CloseHandle
from win32con import THREAD_SUSPEND_RESUME
from win32process import ResumeThread

thread_handle = OpenThread(THREAD_SUSPEND_RESUME, <inherit handle (T/F)>, pipe.tid)
ResumeThread(thread_handle)
CloseHandle(thread_handle)

如果有人知道无需 monkeypatching _execute_child 或任何更好的挂起和恢复进程的方法即可从 Popen 获取线程 ID 的方法,请分享!

资源:

我还创建了一个wrapper for subprocess.Popen,如果有人想看我的具体实现,它会在父进程死亡时杀死子进程。

【讨论】:

    猜你喜欢
    • 2013-05-07
    • 1970-01-01
    • 2017-02-28
    • 2012-03-12
    • 2011-11-26
    • 2011-04-13
    • 2012-09-07
    • 2015-07-07
    • 2017-04-03
    相关资源
    最近更新 更多