尝试在Python3.6中实现`signal.CTRL_C_EVENT` [英] Trying to implement `signal.CTRL_C_EVENT` in Python3.6
问题描述
我正在阅读有关信号的内容,正在尝试实现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.kill
和os.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_CONSOLE
、CREATE_NO_WINDOW
或DETACHED_PROCESS
,它将无法工作。此外,Ctrl+C在这样的过程中被禁用,除非孩子通过WinAPISetConsoleCtrlHandler
手动启用它。
os.kill(os.getpid(), signal.CTRL_C_EVENT)
。否则,行为是未定义的,实际上,它的工作方式类似于发送到进程组ID 0。
这篇关于尝试在Python3.6中实现`signal.CTRL_C_EVENT`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!