kill函数将信号量发送给进程或者进程组,raise函数允许进程向自身发送信号,我们常在终端下杀死一个进程使用kill -9 [pid],这实际上是调用了kill函数给[pid]发送了一个SIGKILL信号量,并且这个信号量不能捕捉,不能忽略,也就是[pid]这个进程收到这个信号就必须得死,如果权限足够的情况下。
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; }这是一个数据结构,这个数据结构中保存了很多信号
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运行以上代码,在终端ctrl+c,当前进程就不会退出了。杀掉此进程的方法是:kill -9 [pid]; 或者:
int main() { kill(10314,9);//10314是要杀死的进程的pid. }我们先来看看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; }类似与setjmp和longjmp,遇到longjmp直接跳转回到setjmp处,适用于函数间的跳转,只不过这里是从信号处理函数中直接跳转到上一个函数中设置sigsetjmp处。例如:
void func1() { signal(SIGINT,sigfunc); //1 sigsetjmp(buf,savemask);<<<------------------ //2 | } | int sigfunc(int sigo) | { | ...//信号处理函数 | siglongjmp(buf,val);---------------------->>> //这后边的代码都不会执行了 }