在Windows上使用python 3.4 我试图终止一个孩子处理模拟一个人按Ctrl + C(Linux上的Ctrl + D)。
我刚刚添加了处理程序以检查信号是否正在处理。 I used the idea from this question
目标是捕获KeyboardInterrupt(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
答案 0 :(得分:1)
它无效,因为您无法使用os.kill
在Windows上发送任意信号:
<强>
os.kill(pid, sig)
强>将信号sig发送到进程pid。特定信号的常数 主机平台上提供的信息在信号模块中定义。
Windows:
signal.CTRL_C_EVENT
和signal.CTRL_BREAK_EVENT
信号 是特殊信号,只能发送到控制台进程 共享公共控制台窗口,例如一些子过程。 任何其他sig
的值将导致进程无条件地被杀死TerminateProcess
API,退出代码将设置为sig 。该 Windows版本的kill()
还需要进程句柄 杀死。
可以通过os.kill
发送的唯一信号是signal.CTRL_C_EVENT
和signal.CTRL_BREAK_EVENT
。其他任何事情都会终止这个过程,这就是你的情况。使用signal.CTRL_C_EVENT
也不会在这里工作,因为通过multiprocessing.Process
启动的进程不是“控制台进程,它与父进程共享一个公共控制台窗口”。我不确定你能在这里用Windows上的信号做多少事情;看起来你不能以TerminateProcess
的方式捕获SIGTERM
在Unix上捕获signal.*_EVENT
的方式,因此在进程终止之前你不能进行任何清理,而你不是为孩子使用控制台应用程序,因此subprocess
将无效。
我认为您的选择是:1)使用shell=True
模块,并使用signal.CTRL+C+EVENT
启动子进程,我相信multiprocessing
将起作用。 2)坚持{{1}}模块,并使用“合作”方法打断工作人员,如multiprocessing.Event
。