很多时候我们写的程序是一个一直运行的,调试的时候,我们直接按ctrl+c终止程序,那么在while后面的一些close函数的调用,在没有设置中断函数的时候,是不会被执行的。
错误例子
#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
while(1){
//sleep(1);
}
printf("closing\n");
}
编译运行,ctrl+c的结果如下:(并不输出closing信息)
cwd@cwd:~/code/test$ g++ test.cpp -o test
cwd@cwd:~/code/test$ ./test
^C
正确的处理方式是自己设置SIGINT的处理函数
正确例子
采用信号集方式
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <assert.h>
using namespace std;
int i;
void close_sig_handler(int sig){
printf("i=%d,closing\n",i);
exit(0);
}
void addsig(int sig,void (*handler)(int) )
{
struct sigaction sa;
memset(&sa,'\0',sizeof(sa));
sa.sa_handler = handler;
sigfillset(&sa.sa_mask);
assert(sigaction(sig,&sa,NULL)!=-1);//捕获到信号sig,使用sa中规定的方法处理
}
int main()
{
i=0;
addsig(SIGINT,close_sig_handler);
while(1){
//sleep(1);
}
i++;
}
编译运行,ctrl+c的结果如下:(输出closing信息)
cwd@cwd:~/code/test$ g++ close.cpp -o close
cwd@cwd:~/code/test$ ./close
^Ci=0,closing
其中,i=0,也是表示,while循化外的语句,一句都不会被执行,与是否阻塞无关。
简单版
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <assert.h>
using namespace std;
int i;
void close_sig_handler(int sig){
printf("i=%d,closing\n",i);
exit(0);
}
int main()
{
struct sigaction sa;
sa.sa_handler = close_sig_handler;
assert(sigaction(SIGINT,&sa,NULL)!=-1);//捕获到信号sig,使用sa中规定的方法处理
i=0;
while(1){
//sleep(1);
}
i++;
}
参考
SIGACTION(2) Linux Programmer's Manual SIGACTION(2)
NAME
sigaction, rt_sigaction - examine and change a signal action
SYNOPSIS
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
sigaction(): _POSIX_C_SOURCE
siginfo_t: _POSIX_C_SOURCE >= 199309L
DESCRIPTION
The sigaction() system call is used to change the action taken by a
process on receipt of a specific signal. (See signal(7) for an over‐
view of signals.)
signum specifies the signal and can be any valid signal except SIGKILL
and SIGSTOP.
If act is non-NULL, the new action for signal signum is installed from
act. If oldact is non-NULL, the previous action is saved in oldact.
The sigaction structure is defined as something like:
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};