我试过这段代码。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
void sighandler(int);
int main()
{
signal(SIGINT, &sighandler);
while(1)
{
sleep(1);
}
return(0);
}
void sighandler(int signum)
{
printf("Caught signal %d, coming out...\n", signum);
exit(1);
}
但是当我按下ctrl + c时,它并没有捕捉到信号。但是当我让它在后台运行并使用kill命令发送SIGINT信号时,它正常工作。请帮助我......
答案 0 :(得分:1)
printf
和exit
在信号处理程序内部调用是不安全的。有关您可以做的有限的事情,请参阅signal(7)。
程序出现故障的直接原因可能是stdout
的文件缓冲区没有被刷新。
此更改应解决此问题:
void sighandler(int signum)
{
char msg[] = "Caught signal, coming out...\n";
write( STDOUT_FILENO, msg, sizeof msg );
_exit(1); // Do not call atexit routines.
}
然而,更好的策略是避免在处理程序中做任何实际工作。只需设置一个标志并返回。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
void sighandler(int);
volatile sig_atomic_t gotsig = 0;
volatile sig_atomic_t signum;
int main()
{
signal(SIGINT, &sighandler);
while(!gotsig)
{
sleep(1);
}
printf("Caught signal %d, coming out...\n", signum);
exit(1);
}
void sighandler(int in_signum)
{
gotsig = 1;
signum = in_signum;
}
答案 1 :(得分:0)
我记得读过sigaction
是首选的功能,而不是signal
,这不是便携式的(非常确定它来自The Linux Programming Interface,这是我认为必不可少的参考资料)。
我的第一个想法是,如果系统不符合POSIX,Ctrl + C可能不会发送SIGINT
信号,因此我制作了一个测试程序,以查看我可以提出的相关信号。当我尝试这个时,@ Potatoswatter的答案突然出现,它似乎与你不能获得输出的直接问题更相关。无论如何,这是一个POSIX友好的源文件来测试四个信号(SIGINT
,SIGTERM
,SIGTSTP
和SIGQUIT
):
#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
void sigHandler(int sig);
static int did_catch = 0;
static int sig_caught = 0;
int main() {
struct sigaction sa;
/* buidl sigaction struct */
sa.sa_handler = sigHandler;
if (sigemptyset(&sa.sa_mask) != 0) { perror("\nsigemptyset"); exit(EXIT_FAILURE); }
sa.sa_flags = 0;
/* handle signals */
if (sigaction(SIGINT, &sa, NULL) != 0) { perror("\nproblem adding SIGINT"); exit(EXIT_FAILURE); }
if (sigaction(SIGTERM, &sa, NULL) != 0) { perror("\nproblem adding SIGTERM"); exit(EXIT_FAILURE); }
if (sigaction(SIGQUIT, &sa, NULL) != 0) { perror("\nproblem adding SIGQUIT"); exit(EXIT_FAILURE); }
if (sigaction(SIGTSTP, &sa, NULL) != 0) { perror("\nproblem adding SIGTSTP"); exit(EXIT_FAILURE); }
/* wait for signal */
while (!did_catch) {
pause();
}
/* check caught signals */
if (sig_caught == SIGINT) printf("\nsignal is SIGINT\n");
else if (sig_caught == SIGTERM) printf("\nsignal is SIGTERM\n");
else if (sig_caught == SIGQUIT) printf("\nsignal is SIGQUIT\n");
else if (sig_caught == SIGTSTP) printf("\nsignal is SIGTSTP\n");
else printf("\nsignal captured is not listed\n");
return 0;
}
void sigHandler(int sig) {
sig_caught = sig;
did_catch = 1;
}
希望这有帮助。