Rui*_*lho 5 python windows multiprocessing
在 Windows 上使用 python 3.4。
我正在尝试终止模拟一个人按 Ctrl+C(在 linux 上为 Ctrl+D)的子进程。
我只是添加了处理程序来检查信号是否正在被处理。我使用了这个问题的想法
目标是捕获 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")
Run Code Online (Sandbox Code Playgroud)
下面是一个输出示例:
C:\Users\Rui>python test.py
[PID:16524] acquiring resources
<Process(Process-1, stopped[2])>
2
joined all processes
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为你不能使用它os.kill在 Windows 上发送任意信号:
os.kill(pid, sig)向进程 pid 发送信号 sig。主机平台上可用的特定信号的常量在信号模块中定义。
Windows:
signal.CTRL_C_EVENT和signal.CTRL_BREAK_EVENT信号是特殊信号,只能发送到共享公共控制台窗口的控制台进程,例如某些子进程。任何其他值都sig将导致进程被TerminateProcessAPI 无条件终止,并且退出代码将设置为 sig。Windows 版本kill()还需要杀死进程句柄。
唯一可以通过 和 发送os.kill的signal.CTRL_C_EVENT信号signal.CTRL_BREAK_EVENT。其他任何事情都会终止该过程,这就是您的情况所发生的情况。使用signal.CTRL_C_EVENT在这里也不起作用,因为通过启动的进程multiprocessing.Process不是“与父级共享公共控制台窗口的控制台进程” 。我不确定 Windows 上的信号能做多少事情;看起来您不被允许以在 Unix 上TerminateProcess捕获的方式捕获SIGTERM,因此您无法在进程终止之前进行任何清理,并且您没有为子进程使用控制台应用程序,所以signal.*_EVENT赢了不工作。
我认为您的选择是:1)使用该subprocess模块,并使用 启动子进程shell=True,我相信这意味着signal.CTRL+C+EVENT会起作用。2)坚持使用multiprocessing模块,并使用“合作”方法来中断工作人员,例如multiprocessing.Event。