记signal和sigaction的一个区别

记signal和sigaction的一个区别

如果需要用相同的方式处理信号多次出现,且信号容易多次出现,则建议使用sigaction函数;若可以保证信号长时间内只出现并只需要处理一次,则可以使用signal函数。

signal函数

signal函数每次设置具体的信号处理函数(非SIG_IGN)只能生效一次,每次在进程响应处理信号时,随即将信号处理函数恢复为默认处理方式。所以如果想多次相同方式处理某个信号,通常的做法是,在响应函数开始,再次调用signal设置,类似于这样:


    int sig_int(); //My signal handler

    ...
    signal(SIGINT, sig_int);
    ...

    int sig_int()
    {
        signal(SIGINT, sig_int);
        ....
    }

PS:假如在信号SIGINT第一次出现之后,sig_int函数开始对该信号进行处理,此时处理还未结束,且还未调用新的一个signal函数,立即产生了第二个SIGINT信号,那么第二个信号会变成执行信号的默认动作,SIGINT的默认动作是终止进程,所以会使得进程退出。并不符合我们的预期,这算是一个隐藏的比较深的bug触发情况。

sigaction函数

  1. 在信号处理程序被调用时,系统建立的新信号屏蔽字会自动包括正被递送的信号。因此保证了在处理一个给定的信号时,如果这种信号再次发生,那么它会被阻塞到对前一个信号的处理结束为止
  2. 响应函数设置后就一直有效,不会重置
  3. 对除SIGALRM以外的所有信号都企图设置SA_RESTART标志,于是被这些信号中断的系统调用(read,write)都能自动再起动。不希望再起动由SIGALRM信号中断的系统调用的原因是希望对I/O操作可以设置时间限制。

猜你喜欢

转载自blog.csdn.net/qq_15437667/article/details/73824717