您的位置:首页 > 其它

【C】——利用sigsuspend函数等待信号阻塞进程

2013-10-21 16:56 519 查看
#include<signal.h>
int sigsuspend(const sigset_t *sigmask);
返回值:-1,并将errno设置为EINTR


  将进程的信号屏蔽字设置为由sigmask指向的值,在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程被挂起。

例子:

  利用sigsuspend函数阻塞子进程;

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>

sig_atomic_t sigflag;
sigset_t newmask,oldmask,zeromask;

void sig_int(int signo)
{
sigflag = 1;
}

void tell_wait(void)
{
sigflag = 0;
if(signal(SIGUSR1,sig_int) == SIG_ERR){
printf("signal error!\n");
exit(1);
}
printf("after signal!\n");
/*
sigemptyset(&newmask);
sigemptyset(&zeromask);
sigaddset(&newmask,SIGINT);
if(sigprocmask(SIG_BLOCK,&newmask,&oldmask) < 0){
printf("sigprocmask error!\n");
exit(1);
}
*/
}

void tell_child(pid_t pid)
{
kill(pid,SIGUSR1);
}

void wait_parent(void)
{
while(sigflag == 0)
sigsuspend(&zeromask);

sigflag = 0;

if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){
printf("sigprocmask erro!\n");
exit(1);
}
}

int main(int argc, char *argv[])
{
pid_t pid;

printf("before signal!\n");

tell_wait();

if((pid = fork()) < 0){
printf("fork error!\n");
exit(1);
}
else if(pid == 0){
wait_parent();
printf("this is child!\n");
exit(0);
}
else{
printf("this is parent!\n");
tell_child(pid);
}
exit(0);
}


例子中的sigprocmask函数是用来检测或更改其信号屏蔽字,或者在一个步骤中同时执行这两个操作。

#include<signal.h>

int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
//返回值:成功返回0,出错返回-1


how: SIG_BLOCK SIG_UNBLOCK SIG_SETMASK

sigprocmask配合sigpending函数使用,

#include<signal.h>

int sigpending(sigset_t *set);
//返回值:成功返回0,出错返回-1


sigpending函数:查询被搁置的信号!

其实sigsuspend是一个原子操作,包含4个步骤:

(1) 设置新的mask阻塞当前进程;
(2) 收到信号,恢复原先mask;
(3) 调用该进程设置的信号处理函数;
(4) 待信号处理函数返回后,sigsuspend返回。

pause函数和sigsuspend函数的区别:

简单的说, sigsuspend = unblock + pause
sigsuspend 函数是用于需要先接触 某个信号的阻塞状态 然后等待该信号发生 这样的应用场景; 而使用 pause 在达到这样的效果时肯定是需要先 调用sigprocmask进行取消阻塞,再调用pause去等待,取消阻塞与等待两步之间有时间窗口,在信号发生在调用pause之前任意时刻的话都有可能导致pause之后再也收不到该信号,也就是永远休眠。为了解决这种情况,sigsuspend函数把这两步做成一个原子操作,这就保证不会丢失(错过)信号,也就不会发生永远休眠这种情况(根本不发生该信号时除外)。所以,建议只用sigsuspend去等待信号。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐