尝试在Python3.6中实现`signal.CTRL_C_EVENT` [英] Trying to implement `signal.CTRL_C_EVENT` in Python3.6

查看:24
本文介绍了尝试在Python3.6中实现`signal.CTRL_C_EVENT`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读有关信号的内容,正在尝试实现signal.CTRL_C_EVENT

据我了解,如果用户在程序运行时按CTRC+C,则会发出信号终止程序。我可以将该程序指定为参数?

我尝试测试用法:

import sys
import signal
import time
import os


os.kill('python.exe', signal.CTRL_C_EVENT)

while(1):
    print ("Wait...")
    time.sleep(10)
但是,我似乎需要一个PID号,而‘python.exe’不起作用。我在进程下找过了,似乎找不到PID号。我确实在服务下面看到了一个PID列,但是服务太多了--我找不到一个python服务。

那么如何找到PID号呢? 另外,SIGNAL_CTRL_C_EVENT是否总是必须在os.kill中使用? 它是否可以用于其他用途?

谢谢。

推荐答案

Windows不实现unix信号,因此Python伪os.kill。不幸的是,它的实现令人困惑。它应该被分成os.killos.killpg,但是我们被一个混合了这两个部分的实现困住了。要发送Ctrl+C或Ctrl+Break,您需要使用os.kill,就好像它真的是os.killpg一样。

signal参数为CTRL_C_EVENT(0)或CTRL_BREAK_EVENT(1)时,os.kill调用WinAPIGenerateConsoleCtrlEvent。这将指示控制台(即承载当前进程的控制台窗口的conhost.exe实例)将事件发送到给定的进程ID(PGID)。组ID 0专门用于将事件广播到连接到控制台的所有进程。否则 进程组ID是进程组中的主导进程的ID。每个进程要么作为新组的领导者创建,要么继承其父进程的组。可以通过CreateProcess创建标志CREATE_NEW_PROCESS_GROUP创建新组。

如果调用GenerateConsoleCtrlEvent失败(例如,当前进程未附加到控制台)或signal参数不是上述控制事件之一,则os.kill尝试使用Terminate Access打开给定进程ID(PID)的句柄,并调用WinAPITerminateProcess。此函数类似于在Unix中发送SIGKILL信号,但带有变量退出代码。请注意,念力操作的是单个进程(即kill),而不是进程组(即killpg)。

Windows不提供获取进程的组ID的函数,因此通常获取有效PGID的唯一方法是自己创建进程。您可以通过creationflags参数将CREATE_NEW_PROCESS_GROUP标志传递给subprocess.Popen。然后,您可以将Ctrl+Break发送给子进程及其在同一组中的所有子进程,但前提是它是一个附加到与当前进程相同的控制台的控制台进程,也就是说,如果您还使用这些标志中的任何一个:CREATE_NEW_CONSOLECREATE_NO_WINDOWDETACHED_PROCESS,它将无法工作。此外,Ctrl+C在这样的过程中被禁用,除非孩子通过WinAPISetConsoleCtrlHandler手动启用它。

仅当您确定当前进程作为组的主导进程启动时才使用os.kill(os.getpid(), signal.CTRL_C_EVENT)。否则,行为是未定义的,实际上,它的工作方式类似于发送到进程组ID 0。

这篇关于尝试在Python3.6中实现`signal.CTRL_C_EVENT`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆