C SIGALRM处理程序在另一个处理程序内时不运行
因此,我正在为一个类做一个关于信号的作业,我们的目标是捕获SIGINT信号,并在用户输入Ctrl-C 5次时请求退出。如果用户在十秒钟内没有回复退出提示,它应该自动退出 我的实现是在不屏蔽SIGALRM的情况下为SIGINT设置一个处理程序,然后从SIGINT处理程序内部调用C SIGALRM处理程序在另一个处理程序内时不运行,c,signals,alarm,C,Signals,Alarm,因此,我正在为一个类做一个关于信号的作业,我们的目标是捕获SIGINT信号,并在用户输入Ctrl-C 5次时请求退出。如果用户在十秒钟内没有回复退出提示,它应该自动退出 我的实现是在不屏蔽SIGALRM的情况下为SIGINT设置一个处理程序,然后从SIGINT处理程序内部调用alarm(),但是从我得到的输出来看,似乎直到SIGINT处理程序运行完毕,SIGALRM处理程序才运行 #include <stdio.h> /* standard I/O functions
alarm()
,但是从我得到的输出来看,似乎直到SIGINT处理程序运行完毕,SIGALRM处理程序才运行
#include <stdio.h> /* standard I/O functions */
#include <stdlib.h> /* exit */
#include <unistd.h> /* standard unix functions, like getpid() */
#include <signal.h> /* signal name macros, and the signal() prototype */
/* first, define the Ctrl-C counter, initialize it with zero. */
int ctrl_c_count = 0;
int got_response = 0;
#define CTRL_C_THRESHOLD 5
/* the Ctrl-C signal handler */
void catch_int(int sig_num)
{
/* increase count, and check if threshold was reached */
ctrl_c_count++;
if (ctrl_c_count >= CTRL_C_THRESHOLD) {
char answer[30];
got_response = 0;
alarm(5);
/* prompt the user to tell us if to really
* exit or not */
printf("\nReally exit? [Y/n]: ");
fflush(stdout);
fgets(answer, sizeof(answer), stdin);
if (answer[0] == 'n' || answer[0] == 'N') {
printf("\nContinuing\n");
fflush(stdout);
/*
* Reset Ctrl-C counter
*/
ctrl_c_count = 0;
got_response = 1;
}
else {
printf("\nExiting...\n");
fflush(stdout);
exit(0);
}
}
}
/* the SIGALRM signal handler */
void catch_alrm(int sig_num)
{
printf("\nGot to alarm handler\n");
if (got_response == 0)
{
printf("User taking too long to respond. Exiting ...\n");
exit(0);
}
}
int main(int argc, char* argv[])
{
struct sigaction sa;
sigset_t mask_set; /* used to set a signal masking set. */
/* setup mask_set */
sigfillset(&mask_set);
sigdelset(&mask_set, SIGALRM);
/* set signal handlers */
// set up the signal handler for Ctrl-C (SIGINT)
sa.sa_handler = catch_int;
sigaction(SIGINT, &sa, NULL);
// set up signal handler for alarm (SIGALRM)
sa.sa_handler = catch_alrm;
sigaction(SIGALRM, &sa, NULL);
while(1)
{
pause();
}
return 0;
}
#包括/*标准I/O功能*/
#包括/*退出*/
#包括/*标准unix函数,如getpid()*/
#包括/*信号名宏和signal()原型*/
/*首先,定义Ctrl-C计数器,并将其初始化为零*/
int ctrl_c_count=0;
int-got_响应=0;
#定义CTRL\u C\u阈值5
/*Ctrl-C信号处理程序*/
无效捕获整数(整数符号数)
{
/*增加计数,并检查是否达到阈值*/
ctrl_c_count++;
如果(ctrl\u c\u计数>=ctrl\u c\u阈值){
答案[30];
got_response=0;
警报(5);
/*提示用户告诉我们是否要
*是否退出*/
printf(“\n是否真正退出?[Y/n]:”);
fflush(stdout);
fgets(答案、尺寸(答案)、标准尺寸);
如果(回答[0]='n'| |回答[0]='n'){
printf(“\n继续\n”);
fflush(stdout);
/*
*重置Ctrl-C计数器
*/
ctrl\u c\u计数=0;
got_response=1;
}
否则{
printf(“\nxiting…\n”);
fflush(stdout);
出口(0);
}
}
}
/*SIGALRM信号处理程序*/
无效捕获数(整数符号数)
{
printf(“\n转到报警处理程序\n”);
if(got_response==0)
{
printf(“用户响应时间过长。正在退出…\n”);
出口(0);
}
}
int main(int argc,char*argv[])
{
struct-sigaction-sa;
sigset_u t mask_set;/*用于设置信号屏蔽集*/
/*设置掩码集*/
sigfillset(&mask_set);
sigdelset(&mask_set,SIGALRM);
/*设置信号处理程序*/
//设置Ctrl-C(SIGINT)的信号处理程序
sa.sa_handler=catch_int;
sigation(SIGINT,&sa,NULL);
//设置报警信号处理器(SIGALRM)
sa.sa_handler=catch_alrm;
sigaction(SIGALRM,&sa,NULL);
而(1)
{
暂停();
}
返回0;
}
有人能告诉我为什么SIGALRM处理程序在SIGINT处理程序完成之前不运行吗?我知道我可能不应该从信号处理程序内部打印东西,但正如我所说的,这是针对类的,我被告知只能这样做
感谢您的任何帮助 信号处理程序应该很短,并且不做任何可以停止进程的事情。例如,您不能停止输入。而且
printf
不是信号安全功能。您需要后退一步,阅读更多关于信号和信号处理的内容。并重新考虑您的设计(或者更确切地说是您的实现)。还要注意,某些信号会阻止其他信号。我知道printf不是一个信号安全函数,但我不允许更改此实现,因为它是用于类的。我所能做的就是为SIGALRM创建一个处理程序,并从SIGINT处理程序内部调用alarm。您的老师是否为SIGINT
处理程序提供了代码?然后你真的应该叫老师,因为他用了一个非常糟糕的例子。是的,我得到了SIGINT处理程序和主函数的代码。我可以和教授谈谈,但我真的认为这不会有多大改变。即使我通过sigdelset
将其他信号解除屏蔽,SIGINT是否也会阻止它们被检测到?SIGALRM的处理程序直到SIGINT处理程序运行完毕才运行。出于某种原因,信号处理程序应该很短,并且不执行任何可能停止进程的操作。例如,您不能停止输入。而且printf
不是信号安全功能。您需要后退一步,阅读更多关于信号和信号处理的内容。并重新考虑您的设计(或者更确切地说是您的实现)。还要注意,某些信号会阻止其他信号。我知道printf不是一个信号安全函数,但我不允许更改此实现,因为它是用于类的。我所能做的就是为SIGALRM创建一个处理程序,并从SIGINT处理程序内部调用alarm。您的老师是否为SIGINT
处理程序提供了代码?然后你真的应该叫老师,因为他用了一个非常糟糕的例子。是的,我得到了SIGINT处理程序和主函数的代码。我可以和教授谈谈,但我真的认为这不会有多大改变。即使我通过sigdelset
将其他信号解除屏蔽,SIGINT是否也会阻止它们被检测到?而SIGALRM的处理程序只是在SIGINT处理程序由于某种原因运行完毕之后才会运行