Python如何在Windows下处理Ctrl-C
实际上,有两个问题。然而,我认为他们是密切相关的,所以我一起问他们。我在Windows下使用Python 2.7.10 32位 第一个是关于这个项目的:Python如何在Windows下处理Ctrl-C,python,windows,signals,Python,Windows,Signals,实际上,有两个问题。然而,我认为他们是密切相关的,所以我一起问他们。我在Windows下使用Python 2.7.10 32位 第一个是关于这个项目的: import sys sys.stdin.readline() a = 1 b = 2 print 'hello' import sys while True: sys.stdin.readline() 当程序要求输入时,如果我按Ctrl-C,程序将被键盘中断停止。但是,此异常将发生在打印“hello”中,而不是在sys.std
import sys
sys.stdin.readline()
a = 1
b = 2
print 'hello'
import sys
while True:
sys.stdin.readline()
当程序要求输入时,如果我按Ctrl-C,程序将被键盘中断停止。但是,此异常将发生在打印“hello”
中,而不是在sys.stdin.readline()中
第二个是关于这个节目:
import sys
sys.stdin.readline()
a = 1
b = 2
print 'hello'
import sys
while True:
sys.stdin.readline()
当我想停止这个程序时,我必须先按Ctrl-C,然后按Enter或再次按Ctrl-C
这两个问题都不是在Linux下发生的,而且在调试时很烦人。如果有人能给我一个详细的解释,我将不胜感激。您可能想检查Win 7+中的SIGINT(ctrl+c
),一个ctrl+c事件在conhost.exe中启动,并跳转到csrss.exe,它在您的进程中创建一个远程线程,从kernel32.dll中的CtrlRoutine
开始。这将调用已注册的控件事件处理程序。进程中的每个C运行时都有一个调用其注册的SIGINT
函数的控制处理程序,该函数将被设置为Python使用的CRT中的Python处理程序。此调用发生在一个新线程上,因此Python的本机处理程序只为主线程设置一个标志,稍后将调用已注册的Python处理程序,例如引发KeyboardInterrupt
的函数。Linux在内核中本机实现信号。因此,底层的read()
系统调用被中断,Python的本机信号处理程序在主线程上执行。然后,当readline
实现恢复时,getc
返回EOF
并设置stdin
流错误状态,errno
设置为EINTR
。鉴于此,Python知道检查其信号标志,并将调用已注册的SIGINT
处理程序,例如引发KeyboardInterrupt
的默认处理程序。这一切都很顺利,因为POSIX系统是为信号设计的,而它们在Windows上是非本机的。请注意,Windows控制台I/O是罕见的同步系统调用会被中断的情况,因此,C运行时在其低级的read
和write
函数中没有将errno
设置为EINTR
。在这种情况下,它可以通过检查错误\u操作\u中止
。Python的I/O实现也不检查这一点,除了在REPL和内置的raw\u input
和input
(即PyOS\u StdioReadline
)中用于读取输入的代码中。Python 3使用Windows事件对象来帮助在这种竞争条件下进行同步,但仍有改进的余地。我在Windows 8+中提到了上述更改,因为它在ReadFile
和WriteFile
中引入了一个bug。当操作中断时,他们不再设置错误\u操作\u中止
。现在Python的PyOS\u StdioReadline
无法区分文件结尾(EOF
)和Windows 8+中的中断读取。因此,Ctrl+C使REPL退出,就像您输入了Ctrl+Z.和raw_input
和input
seteoferor
,这与检查由Ctrl+C线程设置的SIGINT
标志相匹配。解决方法包括完全重写以使用ReadConsole
API。