1 kill和raise函数
#include<signal.h>
int kill(pid_t pid,int signo);//pid>0 将信号发送给进程ID==PID的进程
//pid==0 讲信号发送给其进程组ID等于发送进程的进程组ID的进程组
kill函数将信号量发送给进程或者进程组,raise函数允许进程向自身发送信号,我们常在终端下杀死一个进程使用kill -9 [pid],这实际上是调用了kill函数给[pid]发送了一个SIGKILL信号量,并且这个信号量不能捕捉,不能忽略,也就是[pid]这个进程收到这个信号就必须得死,如果权限足够的情况下。
2 alrm和pause函数
unsigned int alrm(unsigned int seconds);
int pause(void);
alrm函数设定一个时间值,比如alarm(5),五秒之后将会产生SIGALRM信号,如果不捕捉这个信号,当前进程将会终止。
int main()
{
signal(SIGALRM,fun);//注册了捕捉函数后,闹钟时间到进入处理函数,如果注释掉这句,闹钟时间到会终止当前进程
alarm(5);
while(1);
}
void fun(int signo)
{
cout<<"收到了alarm信号"<<endl;
}
pause函数使调用进程挂起,直到捕捉到一个信号,只有执行了一个信号处理程序并从其返回时,pause才返回,这种情况下pause返回-1;
int main()
{
signal(SIGALRM,fun_sigint);
cout<<"pause在等待信号处理程序"<<endl;
alarm(5);
pause();//进程会阻塞在这里,直到fun函数返回
cout<<"pause函数返回了"<<endl;
while(1);
}
void fun(int signo)
{
cout<<"收到了alarm信号"<<endl;
}
3 信号集
这是一个数据结构,这个数据结构中保存了很多信号
sigset_t set;
int sigemptyset(sigset_t *set);//清空当前信号集合
int sigaddset(sigset_t *set,int signo);//将信号量signo添加到信号集中
int sigismember(const sigset_t *set,int signo);//信号signo在信号集返回1,否则返回0
4 sigprocmask函数
int sigprocmask(int how,const sigset_t *set,sigset_t *oset);
//set是一个信号集,根据前边的how决定如何处理这个集中的信号(屏蔽set中的信号,解除屏蔽),oset返回一个集合,这个集合记录了当前进程屏蔽了哪些信号,关于how:
//SIG_BLOCK :屏蔽set信号集中所有的信号
//SIG_UNBLOCK :该进程新的屏蔽字是当前的屏蔽字和set指向的信号的交集
//SIG_SETMASK :该进程新的信号屏蔽字是set指向的值
int main()
{
sigset_t set;
sigemptyset(&set);//清空set
sigaddset(&set,SIGINT);//将ctrl+c添加到set中
sigprocmask(SIG_BLOCK,&set,NULL);//屏蔽此信号集中的信号
while(1);
}
运行以上代码,在终端ctrl+c,当前进程就不会退出了。杀掉此进程的方法是:kill -9 [pid]; 或者:
int main()
{
kill(10314,9);//10314是要杀死的进程的pid.
}
5 sigpending函数
int sigpending(sigset_t *set);//返回当前进程被阻塞不能传递的信号集,通过set(传指针)返回,成功函数返回0,出错返回-1.
6 sigaction函数
我们先来看看sigaction这个结构体:
struct sigation
{
void (*sa_handler)();//信号处理函数
sigset_set sa_mask;//屏蔽字
int sa_flags;
}
//sigation函数
int sigaction(int sigo,const struct sigaction *act,struct sigaction *oact);
这个我们可以理解为高级版的signal函数,可以修改其屏蔽字,处理函数。
int main()
{
struct sigaction action;
action.sa_handler=fun_sigint;//设置信号处理函数
action.sa_flags=0;
sigemptyset(&action.sa_mask);//清空屏蔽字
sigaddset(&action.sa_mask,SIGINT);//添加SIGINT到屏蔽字中
sigprocmask(SIG_BLOCK,&action.sa_mask,NULL);//屏蔽屏蔽集中的信号
sigaction(SIGQUIT,&action,NULL);//捕捉SIGQUIT信号
while(1);
}
void fun_sigint(int signo)
{
cout<<"SIGQUIT"<<endl;
}
7 sigsetjmp和siglongjmp函数
类似与setjmp和longjmp,遇到longjmp直接跳转回到setjmp处,适用于函数间的跳转,只不过这里是从信号处理函数中直接跳转到上一个函数中设置sigsetjmp处。例如:
void func1()
{
signal(SIGINT,sigfunc);
//1
sigsetjmp(buf,savemask);<<<------------------
//2 |
} |
int sigfunc(int sigo) |
{ |
...//信号处理函数 |
siglongjmp(buf,val);---------------------->>>
//这后边的代码都不会执行了
}
8sigsuspend函数
int sigsuspend(const sigset_t *sigmask); //屏蔽sigmask中的信号量,并且阻塞,直到从任何一个信号处理函数返回
int main()
{
sigset_t set;
signal(SIGQUIT,fun_sigint);
sigemptyset(&set);
sigaddset(&set,SIGINT);
sigsuspend(&set);//阻塞,并且屏蔽掉SIGINT信号
while(1);
}
void fun_sigint(int signo)
{
cout<<"进入了处理函数"<<endl;
}