在ncurses中处理信号
我正在使用ncurses用C编写一个程序。我正在尝试处理crtlc信号。在我的代码中,这个信号被捕获并处理,但程序没有正确终止。这可能是我离开ncurses的方式吗在ncurses中处理信号,c,signals,ncurses,sigint,C,Signals,Ncurses,Sigint,我正在使用ncurses用C编写一个程序。我正在尝试处理crtlc信号。在我的代码中,这个信号被捕获并处理,但程序没有正确终止。这可能是我离开ncurses的方式吗 //handle SIGINT signal void handle_signal(int signal){ if(signal == SIGINT){ clear(); mvprintw(3,3,"A SIGNAL WAS ENCOUNTERED"); refresh();
//handle SIGINT signal
void handle_signal(int signal){
if(signal == SIGINT){
clear();
mvprintw(3,3,"A SIGNAL WAS ENCOUNTERED");
refresh();
sleep(1/2);
exit(0);
} //close if statement
}//close handle_signal() function
如果没有进一步的研究:如果
诅咒
函数实际上是信号安全的,我会非常惊讶。通常,保持信号处理程序最小是最好的做法,理想情况下只需设置一个标志。所以,你应该这样解决你的问题:
static volatile sig_atomic_t interrupted = 0;
在信号处理器中:
if (signal == SIGINT)
{
interrupted = 1;
}
在主循环的某个地方:
if (interrupted)
{
clear();
mvprintw(3,3,"A SIGNAL WAS ENCOUNTERED");
refresh();
sleep(1);
endwin();
exit(0);
}
请注意,您的代码没有在任何地方调用
endwin()
,这是将终端恢复到正常状态所必需的。无需进一步研究:如果诅咒
函数实际上是信号安全的,我会非常惊讶。通常,保持信号处理程序最小是最好的做法,理想情况下只需设置一个标志。所以,你应该这样解决你的问题:
static volatile sig_atomic_t interrupted = 0;
在信号处理器中:
if (signal == SIGINT)
{
interrupted = 1;
}
在主循环的某个地方:
if (interrupted)
{
clear();
mvprintw(3,3,"A SIGNAL WAS ENCOUNTERED");
refresh();
sleep(1);
endwin();
exit(0);
}
注意:您的代码没有在任何地方调用endwin()
,这是将终端恢复到正常状态所必需的。如中所述,ncurses为SIGINT安装处理程序
处理程序尝试在退出时清理屏幕。虽然
通常按预期工作,但存在以下限制:
如果在initscr
(或newterm
)之前设置处理程序,则不会调用它。如果在之后设置处理程序,则必须考虑信号处理程序中可以安全调用的函数的各种限制
ncurses对SIGINT的处理考虑到了这样一个事实,即它通常使用的一些功能是不安全的,并且在接收到信号时使用了不同的策略(这可能不是100%可靠,而是一种改进)
您的信号处理程序不考虑这些,例如,ncurses可以调用malloc
来处理所需的额外输出缓冲,并且“不工作”,因为malloc
不是一个安全的函数
进一步阅读:
- (及)
如中所述,ncurses为SIGINT
处理程序尝试在退出时清理屏幕。虽然
通常按预期工作,但存在以下限制:
如果在initscr
(或newterm
)之前设置处理程序,则不会调用它。如果在之后设置处理程序,则必须考虑信号处理程序中可以安全调用的函数的各种限制
ncurses对SIGINT的处理考虑到了这样一个事实,即它通常使用的一些功能是不安全的,并且在接收到信号时使用了不同的策略(这可能不是100%可靠,而是一种改进)
您的信号处理程序不考虑这些,例如,ncurses可以调用malloc
来处理所需的额外输出缓冲,并且“不工作”,因为malloc
不是一个安全的函数
进一步阅读:
- (及)
睡眠(1/2)
?这是两个整数,所以除法的结果也是一个整数。因此,这与调用sleep(0)
相同。这就是你想要的吗?我这么做只是为了测试看看打印出来的信息。。它不能解决任何问题:(sleep(1/2)
?这是两个整数,因此除法的结果也将是一个整数。这与调用sleep(0)
相同。这是您想要的吗?我这样做只是为了测试查看打印的消息。它不能解决任何问题:(