试图在Python3.6中实现`signal.CTRL_C_EVENT`

时间:2017-05-23 01:21:57

标签: windows python-3.x signals

我正在阅读有关信号的信息并试图实施library(stringr) unlist(strsplit(str_extract_all(string,'(?<=\\=)([^_]+)')[[1]],'--')) [1] "621729" "twenty" "One" "Forty"

根据我的理解,如果用户在程序运行时按下CTRC + C,将发送一个信号来杀死一个程序。我可以将程序指定为参数吗?

我尝试测试用法:

signal.CTRL_C_EVENT

然而,似乎我需要一个pid号和&#39; python.exe&#39;不起作用。我查看了流程,我似乎无法找到一个PID号码。我确实在服务下看到了一个PID列,但是有很多服务 - 我找不到python。

那么如何找到PID号? 另外,signal_CTRL_C_EVENT总是必须在os.kill中使用吗? 它可以用于其他目的吗?

谢谢。

2 个答案:

答案 0 :(得分:1)

你可以通过os.getpid()

获得pid
os.kill(os.getpid(), signal.CTRL_C_EVENT)

答案 1 :(得分:1)

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会调用WinAPI GenerateConsoleCtrlEvent。这指示控制台(即托管当前进程的控制台窗口的conhost.exe实例)将事件发送到给定进程 ID(PGID)。组ID 0是特殊的,用于将事件广播到连接到控制台的所有进程。除此以外 进程组ID是进程组中的潜在进程的ID。每个进程都被创建为新组的领导者或继承其父组的组。可以通过CreateProcess创建标记CREATE_NEW_PROCESS_GROUP创建新组。

如果调用GenerateConsoleCtrlEvent失败(例如当前进程未附加到控制台)或signal参数不是上述控制事件之一,则{{1}而是尝试使用终止访问打开给定进程ID(PID)的句柄并调用WinAPI os.kill。这个函数就像在Unix中发送TerminateProcess信号,但是带有变量退出代码。请注意混淆,因为它在单个流程(即SIGKILL)上运行,而不是流程组(即kill)。

Windows不提供获取进程的组ID的功能,因此获取有效PGID的唯一方法通常是自己创建进程。您可以通过killpg参数将CREATE_NEW_PROCESS_GROUP标记传递给subprocess.Popen。然后,您可以将Ctrl + Break发送到子进程及其位于同一组中的所有子进程,但前提是它是一个与当前进程连接到同一控制台的控制台进程,即如果您也是也可以使用以下任何标志:creationflagsCREATE_NEW_CONSOLECREATE_NO_WINDOW。此外,在此过程中禁用Ctrl + C,除非子项通过WinAPI DETACHED_PROCESS手动启用它。

当您确定当前流程是作为群组的潜在客户启动时,仅使用SetConsoleCtrlHandler。否则,行为是未定义的,实际上它的工作方式就像发送到进程组ID 0。