gpt4 book ai didi

python - 使用 os.kill 将 SIGINT 发送到 Python 子进程,就像按 Ctrl+C 一样

转载 作者:可可西里 更新时间:2023-11-01 14:24:06 24 4
gpt4 key购买 nike

在 Windows 上使用 python 3.4。
我正在尝试终止模拟一个人按 Ctrl+C(在 Linux 上为 Ctrl+D)的子进程。

我刚刚添加了处理程序来检查信号是否被处理了。 I used the idea from this question

目标是捕获键盘中断(SIGINT),并释放资源。但是,如果 SIGINT 不是来自键盘,似乎不会抛出异常。这就是为什么我创建了一个处理程序,但该进程似乎根本没有运行该处理程序...

import multiprocessing
import time
import signal
import signal
import os
import sys

def handler(signal, frame):
print("handler!!!")
sys.exit(10)

def worker():
p = multiprocessing.current_process()
try:
signal.signal(signal.SIGINT,handler)
print("[PID:{}] acquiring resources".format(p.pid))
while(True):
#working...
time.sleep(0.5)
except (KeyboardInterrupt, SystemExit):
pass
finally:
print("[PID:{}] releasing resources".format(p.pid))

if __name__ == "__main__":
lst = []
for i in range(1):
p = multiprocessing.Process(target=worker)
p.start()
lst.append(p)

time.sleep(3)
for p in lst:
os.kill(p.pid,signal.SIGINT)
p.join()
print(p)
print(p.exitcode)
print("joined all processes")

这是一个输出示例:

C:\Users\Rui>python test.py
[PID:16524] acquiring resources
<Process(Process-1, stopped[2])>
2
joined all processes
  • 我做错了什么?
  • 我应该使用 subprocess 模块吗?
  • 我可以尝试使用哪些其他方法来中断流程执行?

最佳答案

它不起作用,因为您不能使用 os.kill在 Windows 上发送任意信号:

os.kill(pid, sig)

Send signal sig to the process pid. Constants for the specific signals available on the host platform are defined in the signal module.

Windows: The signal.CTRL_C_EVENT and signal.CTRL_BREAK_EVENT signals are special signals which can only be sent to console processes which share a common console window, e.g., some subprocesses. Any other value for sig will cause the process to be unconditionally killed by the TerminateProcess API, and the exit code will be set to sig. The Windows version of kill() additionally takes process handles to be killed.

唯一可以通过 os.kill 发送的信号是 signal.CTRL_C_EVENTsignal.CTRL_BREAK_EVENT。其他任何事情都会终止该过程,这就是您的情况。使用 signal.CTRL_C_EVENT 在这里也不起作用,因为通过 multiprocessing.Process 启动的进程不是“共享公共(public)控制台窗口的控制台进程” 与 parent 。我不确定您可以在这里使用 Windows 上的信号做很多事情;看起来你不能像在 Unix 上捕获 SIGTERM 那样捕获 TerminateProcess,所以你不能在进程终止之前做任何清理,并且您没有为 child 使用控制台应用程序,因此 signal.*_EVENT 将不起作用。

我认为您的选择是:1) 使用 subprocess 模块,并使用 shell=True 启动子进程,我相信这意味着 signal。 CTRL+C+EVENT 将起作用。 2) 坚持使用multiprocessing 模块,并使用一种“合作”的方式来打断worker,比如multiprocessing.Event。 .

关于python - 使用 os.kill 将 SIGINT 发送到 Python 子进程,就像按 Ctrl+C 一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26578799/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com