使用os.kill将SIGINT发送到Python子进程,就像按Ctrl + C一样 [英] Send SIGINT to Python subprocess using os.kill as if pressing Ctrl+C
问题描述
在Windows上使用python 3.4.
我试图终止模拟Ctrl + C(在Linux上为Ctrl + D)的人的子进程.
Using python 3.4 on windows.
I am trying to terminate a child processing simulating a person pressing Ctrl+C (Ctrl+D on linux).
我刚刚添加了处理程序,以检查信号是否已被处理. 我使用了这个问题的想法
I just added the handler to check if the signal was being handled at all. I used the idea from this question
目标是捕获KeyboardInterrupt(SIGINT),并释放资源.但是,如果SIGINT不是来自键盘,则似乎不会引发异常.这就是为什么我创建了一个处理程序,但是该进程似乎根本没有运行该处理程序的原因...
The objective is to catch the KeyboardInterrupt (SIGINT), and release the resources. But it seems that the exception is not thrown if SIGINT doesnt come from the keyboard. That's why I created an handler, but the process doesnt seem to run the handler at all...
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
- 我在做什么错了?
- 我应该使用子流程模块吗?
- 我还可以尝试其他哪些方法来中断流程执行?
推荐答案
It's not working because you can't use os.kill
to send arbitrary signals on Windows:
os.kill(pid, sig)
os.kill(pid, sig)
将信号sig发送到进程pid.特定信号的常数 主机平台上可用的信号在信号模块中定义.
Send signal sig to the process pid. Constants for the specific signals available on the host platform are defined in the signal module.
Windows:signal.CTRL_C_EVENT
和signal.CTRL_BREAK_EVENT
信号
是特殊信号,只能发送到控制台进程
共享一个公共控制台窗口,例如一些子进程. 其他
sig
的值将导致进程无条件地被终止
TerminateProcess
API,并且退出代码将设置为sig .这
Windows版本的kill()
另外需要处理句柄
被杀死.
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_EVENT
和signal.CTRL_BREAK_EVENT
.其他任何事情都会终止该过程,这就是您所遇到的情况.使用signal.CTRL_C_EVENT
在这里也不起作用,因为通过multiprocessing.Process
启动的进程不是与父进程共享公共控制台窗口的控制台进程" .我不确定在Windows上您可以在这里做很多事情.看起来不像在Unix上捕获SIGTERM
的方式那样允许您捕获TerminateProcess
,因此您无法在进程终止之前进行任何清理,并且您没有使用控制台应用程序为了孩子,所以signal.*_EVENT
将不起作用.
The only signals that can be sent via os.kill
are signal.CTRL_C_EVENT
and signal.CTRL_BREAK_EVENT
. Anything else just terminates the process, which is what is happening in your case. Using signal.CTRL_C_EVENT
won't work here, either, because processes started via multiprocessing.Process
aren't "console processes which share a common console window" with the parent. I'm not sure there's much you can do here with signals on Windows; It doesn't look like you're allowed to catch TerminateProcess
the way you can catch SIGTERM
on Unix, so you can't do any clean up prior to the process terminating, and you're not using a console application for the child, so signal.*_EVENT
won't work.
我认为您的选择是:1)使用subprocess
模块,并使用shell=True
启动子进程,我相信这意味着signal.CTRL+C+EVENT
将起作用. 2)坚持使用multiprocessing
模块,并使用合作"方式中断工作程序,例如 multiprocessing.Event
.
I think your options are: 1) Use the subprocess
module, and launch the child process with shell=True
, which I believe will mean signal.CTRL+C+EVENT
will work. 2) Stick with the multiprocessing
module, and use a "co-operative" method of interrupting the worker, like multiprocessing.Event
.
这篇关于使用os.kill将SIGINT发送到Python子进程,就像按Ctrl + C一样的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!