linux c++(信号介绍)
信号的处理包括信号的发送、捕捉和处理,它们有各自相对应的常见函数
-
发生信号的函数
kill()、raise()、alarm()、setitimer()、sigqueue() -
捕捉信号的函数
alarm()、pause() -
处理信号的函数
signal()、sigaction()
函数介绍 kill()、raise()
- raise()函数允许进程向自身发送信号
- kill()函数不仅可以终止进程(实际上是通过发出SIGKILL信号终止),也可以向进程发送其他信号


函数介绍 alarm()、pause()
- alarm()也称为闹钟函数,它可以在进程中设置一个定时器,当定时器指定的时间到时,它就向进程发送SIGALARM信号。要注意的是,一个进程只能有一个闹钟时间
- pause()函数用于将调用进程挂起直至捕捉到信号为止。这个函数很常用,通常可以用于判断信号是否已到。


函数介绍 signal()、sigaction()
- 使用signal()函数处理时,只需指出要处理的信号和处理函数即可。它主要用于前32种非实时信号的处理,不支持信号传递信息


处理信号的流程

尽量避免使用此函数进行捕捉,因为signal函数有时可能在其他函数中有其他的含义
typedef void(*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler);
signum 要捕捉的信号
handler 要执行的捕捉函数指针,函数应该声明void func(int);
注册捕捉函数
struct sigaction {
void (*sa_handler)(int);//函数指针
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;//执行捕捉函数期间,临时屏蔽的信号集
int sa_flags;//一般填0,若不写0,SA_SIGINFO会使用第二个函数指针
void (*sa_restorer)(void);//无效
};
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact);
signum 捕捉的信号
act 传入的动作
oldact 原动作,恢复现场
示例
void sigCatchFun(int num)
{
printf("beng call %d\n",num);
sleep(5);
printf("end call %d\n",num);
}
int main()
{
//注册捕捉函数 #include <signal.h>
struct sigaction act;
act.sa_flags=0;
act.sa_handler = sigCatchFun;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask,SIGQUIT); //临时屏蔽ctrl + \信号
sigaction(SIGINT,&act,NULL);
while(1)
{
printf("who can kill me?\n");
sleep(1);
}
return 0;
}
信号屏蔽
sigset_t set; // typedef unsigned long sigset_t;
int sigemptyset(sigset_t *set); 将某个信号集清0 成功:0;失败:-1
int sigfillset(sigset_t *set); 将某个信号集置1 成功:0;失败:-1
int sigaddset(sigset_t *set, int signum); 将某个信号加入信号集 成功:0;失败:-1
int sigdelset(sigset_t *set, int signum); 将某个信号清出信号集 成功:0;失败:-1
int sigismember(const sigset_t *set, int signum);判断某个信号是否在信号集中 返回值:在集合:1;不在:0;出错:-1
sigprocmask
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); 成功:0;失败:-1,设置errno
参数:
set:传入参数,是一个位图,set中哪位置1,就表示当前进程屏蔽哪个信号。
oldset:传出参数,保存旧的信号屏蔽集。
how参数取值: 假设当前的信号屏蔽字为mask
1.SIG_BLOCK: 当how设置为此值,set表示需要屏蔽的信号。相当于 mask = mask|set
2.SIG_UNBLOCK: 当how设置为此,set表示需要解除屏蔽的信号。相当于 mask = mask & ~set
3.SIG_SETMASK: 当how设置为此,set表示用于替代原始屏蔽及的新屏蔽集。相当于 mask = set若,调用sigprocmask解除了对当前若干个信号的阻塞,则在sigprocmask返回前,至少将其中一个信号递达。
sigpending
读取当前进程的未决信号集
int sigpending(sigset_t *set); set传出参数。 返回值:成功:0;失败:-1,设置errno
信号忽略
// 方案一
if(signal(SIGHUP,SIG_IGN) == SIG_ERR)
{
perror("signal ignore SIGHUB");
exit(1);
}
// 方案二
sigset_t myset,oldset;
sigemptyset(&myset);
sigaddset(&myset,SIGINT);
sigprocmask(SIG_BLOCK,&myset,&oldset)
浙公网安备 33010602011771号