如何关闭在Windows上运行其他子过程的子过程?

发布于 2025-02-06 17:42:41 字数 2301 浏览 2 评论 0原文

我面临以下问题,无法解决。

  1. a 运行 b AS Multiprocessing.process()
  2. b b 运行 c as subprocess.run()
  3. a terminates b by multiprocessing.process.process.ternication.terminate(
  4. ) b>和 c 被终止
    结果: b 被终止, c 在后台运行

重要的附加信息

  • a b c 是程序
  • a 是我的程序,我开发
  • b c 是我不是由我开发的外部程序我没有控制 解决方案
  • 必须在 Windows 问题上工作

是否有人有任何解决方案或知道是否不可能?

以下代码在示例中描述了我的问题:

# main.py - Process A
# Runs Process B
import multiprocessing
from Manager import manager
from time import sleep

def main():
    proc = multiprocessing.Process(target=manager)

    proc.start()
    print("[MAIN] Process going sleep")
    sleep(3)
    print("[MAIN] Process is awake now. Beginning to terminate")
    proc.terminate()
    proc.join()
    print("[MAIN] Process Manager terminated.")

if __name__ == "__main__":
    main()
# Manager.py - Process B
# Cannot change any code
# Runs process C
import subprocess

def manager():
    print("[MANAGER] START")
    subprocess.run(["python", "sleepery.py"])
    print("[MANAGER] Terminated")
# sleepery.py - Process C
# Cannot change any code
from time import sleep

def sleeper():
    """This process prints info every two seconds for 8"""
    for _ in range(4):
        sleep(2)
        print(f"[SLEEPER] prints!")
    print("[SLEEPER] ends")

if __name__ == "__main__":
    sleeper()

输出

[MAIN] Process going sleep
[MANAGER] START
[SLEEPER] prints!
[MAIN] Process is awake now. Beginning to terminate
[MAIN] Process Manager terminated.
[SLEEPER] prints! 
[SLEEPER] prints!
[SLEEPER] prints!
[SLEEPER] ends

想要输出

[MAIN] Process going sleep
[MANAGER] START
[SLEEPER] prints!
[MAIN] Process is awake now. Beginning to terminate
[MAIN] Process Manager terminated.

我的研究
唯一有效的是通过Taskskill
杀死所有Python进程 但这并不完全是优雅的

I am facing the following problem and can't solve it.

  1. A runs B as multiprocessing.Process()
  2. B runs C as subprocess.run()
  3. A terminates B by multiprocessing.Process.terminate()
  4. Expected: B and C are terminated
    Result: B is terminated and C runs in background

Important additional information

  • A, B, C are programs
  • A is my program that I develop
  • B, C are external programs not developed by me and I have no control
    of
  • Solution must work on Windows

Question Does anyone have any solution or know if it isn't possible?

Following code describes my problem on example:

# main.py - Process A
# Runs Process B
import multiprocessing
from Manager import manager
from time import sleep

def main():
    proc = multiprocessing.Process(target=manager)

    proc.start()
    print("[MAIN] Process going sleep")
    sleep(3)
    print("[MAIN] Process is awake now. Beginning to terminate")
    proc.terminate()
    proc.join()
    print("[MAIN] Process Manager terminated.")

if __name__ == "__main__":
    main()
# Manager.py - Process B
# Cannot change any code
# Runs process C
import subprocess

def manager():
    print("[MANAGER] START")
    subprocess.run(["python", "sleepery.py"])
    print("[MANAGER] Terminated")
# sleepery.py - Process C
# Cannot change any code
from time import sleep

def sleeper():
    """This process prints info every two seconds for 8"""
    for _ in range(4):
        sleep(2)
        print(f"[SLEEPER] prints!")
    print("[SLEEPER] ends")

if __name__ == "__main__":
    sleeper()

OUTPUT

[MAIN] Process going sleep
[MANAGER] START
[SLEEPER] prints!
[MAIN] Process is awake now. Beginning to terminate
[MAIN] Process Manager terminated.
[SLEEPER] prints! 
[SLEEPER] prints!
[SLEEPER] prints!
[SLEEPER] ends

WANTED OUTPUT

[MAIN] Process going sleep
[MANAGER] START
[SLEEPER] prints!
[MAIN] Process is awake now. Beginning to terminate
[MAIN] Process Manager terminated.

My research
The only thing that works is to kill all python processes by taskkill
But it isn't exactly graceful

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

所有深爱都是秘密 2025-02-13 17:42:41

使用 job对象,这允许您分组这项工作中的所有儿童流程都在一步中杀死他们。

Use a Job object, this allows you to group all child processes in this job and kill them all in a single step.

晒暮凉 2025-02-13 17:42:41

安德斯的答案直接进入了这一点。
这是重构 main.py 使用作业对象,

# main.py - Process A
# Runs Process B
import multiprocessing

import win32api
from Manager import manager
from time import sleep
import time
import win32job
import win32con

def main():
    jobHandle = win32job.CreateJobObject(None, "")
    proc = multiprocessing.Process(target=manager)
    proc.start()
    # Get handle to process and assign process to job object
    handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, proc.pid)
    win32job.AssignProcessToJobObject(jobHandle, handle)
    print("[MAIN] Process going sleep")
    sleep(3)
    print("[MAIN] Process is awake now. Beginning to terminate")
    win32job.TerminateJobObject(jobHandle, 0)
    print("[MAIN] Process Manager and his kids terminated.")

if __name__ == "__main__":
    main()

然后输出

> python .\main.py
[MAIN] Process going sleep
[MANAGER] START
[SLEEPER] prints!
[MAIN] Process is awake now. Beginning to terminate
[MAIN] Process Manager and his kids terminated.

Anders's answer goes right into the point.
Here is refactored main.py to use Job Objects

# main.py - Process A
# Runs Process B
import multiprocessing

import win32api
from Manager import manager
from time import sleep
import time
import win32job
import win32con

def main():
    jobHandle = win32job.CreateJobObject(None, "")
    proc = multiprocessing.Process(target=manager)
    proc.start()
    # Get handle to process and assign process to job object
    handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, True, proc.pid)
    win32job.AssignProcessToJobObject(jobHandle, handle)
    print("[MAIN] Process going sleep")
    sleep(3)
    print("[MAIN] Process is awake now. Beginning to terminate")
    win32job.TerminateJobObject(jobHandle, 0)
    print("[MAIN] Process Manager and his kids terminated.")

if __name__ == "__main__":
    main()

Then output:

> python .\main.py
[MAIN] Process going sleep
[MANAGER] START
[SLEEPER] prints!
[MAIN] Process is awake now. Beginning to terminate
[MAIN] Process Manager and his kids terminated.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文