Python Windows:Jupyter如何抛出键盘中断?
我知道如何中断内核(例如轻触Python Windows:Jupyter如何抛出键盘中断?,python,c++,jupyter-notebook,python-c-api,keyboardinterrupt,Python,C++,Jupyter Notebook,Python C Api,Keyboardinterrupt,我知道如何中断内核(例如轻触I两次或在web界面上中断内核)。但是,我为Python(我使用Windows)构建了一个C扩展,它处理我的C++代码中的CTRL C事件(一个玩具例子): static int s_interrupted=0; 布尔WINAPI控制台句柄(DWORD fdwCtrlType){ 开关(fdwCtrlType) { //处理CTRL-C信号。 案例控制事件: s_=1; 返回TRUE; } } int main(){ s_=0; int输出=1; if(!setCon
I
两次或在web界面上中断内核)。但是,我为Python(我使用Windows)构建了一个C扩展,它处理我的C++代码中的CTRL C事件(一个玩具例子):
static int s_interrupted=0;
布尔WINAPI控制台句柄(DWORD fdwCtrlType){
开关(fdwCtrlType)
{
//处理CTRL-C信号。
案例控制事件:
s_=1;
返回TRUE;
}
}
int main(){
s_=0;
int输出=1;
if(!setConsoleHandler(consoleHandler,TRUE)){
std::cout您的代码未安装信号处理程序,并且未使用s\u signal\u handler
。您需要调用signal
函数来注册回调
#include <atomic>
#include <signal.h>
::std::atomic<bool> s_interrupted{};
static void signal_handler(int signal)
{
s_interrupted = true;
}
int main()
{
::signal(SIGINT, &::signal_handler);
#包括
#包括
::std::原子s_中断{};
静态无效信号处理器(int信号)
{
s_=真;
}
int main()
{
::信号(SIGINT,&::信号处理器);
这里不能使用consoleHandler()
,因为这里没有控制台。IPython内核是一个“无头”子进程,由Jupyter前端根据请求执行代码
为了中断正在运行的IPython内核,Jupyter前端使用SIGINT
信号。它在POSIX和Windows上都这样做;在Windows上,Jupyter使用构建在其周围的附加基础设施,并实现与POSIXos.killpg(PID,SIGINT)相同的结果
call;一个单独的线程轮询事件并在主线程中触发一个SIGINT
信号
请注意,IPython内核为其处理的每条消息显式恢复Python默认信号处理程序。请参阅:
及
这两个钩子在每个消息处理程序之前和之后执行(例如for,包括)
它是signal。在主Python线程中引发KeyboardInterrupt
的默认\u int\u处理程序
。如果您的代码必须检测中断,则每次IPython执行单元格时,它都需要注册自己的signal
处理程序
附带说明:一个独立的交互式Python解释器也不使用SetConsoleCtrlHandler
来检测键盘中断;Python源代码中唯一使用的地方是,只有这样才能始终使用返回TRUE
的处理程序使控制代码静音。相反,Python依赖于更新了我的代码。s\u信号处理程序
在这里不是必需的。我已经有了控制台处理程序
。什么是::signal()
do?@user1691278signal
函数注册信号处理程序,这样您就可以实际处理SIGINT
而不是SetConsoleCtrlHandler
做这项工作了吗?@user1691278有点做,但它是windows特有的东西,信号处理程序更具可移植性。CTRL+C
与SIGI不完全相同NT
那么什么是CTRL+C
呢?你读过吗?重新启动内核只是从前端到后端的另一条消息。
#include <atomic>
#include <signal.h>
::std::atomic<bool> s_interrupted{};
static void signal_handler(int signal)
{
s_interrupted = true;
}
int main()
{
::signal(SIGINT, &::signal_handler);
self.saved_sigint_handler = signal(SIGINT, default_int_handler)
signal(SIGINT, self.saved_sigint_handler)