Linux C 信号 pause、sigsuspend 的相同与区别

https://www.cnblogs.com/mrethan/p/5612839.html

  • pause函数:

       功能:让进程暂停直到信号出现

       #include<unistd.h>

       intpause();

       函数说明:pause()会令目前的进程暂停(进入睡眠状态),直至信号(signal)所中断。

       返回值:只返回-1。

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

void deal()
{
   printf(“信号干扰!\n”);
}
void main()
{
     printf(“进程执行!\n”);
    signal(SIGINT,deal);
    pause();
    printf(“进程结束!\n”);
}

说明:

当程序运行时,pause会使当前的进程挂起(进入睡眠状态),直到我们向该进程发送SIGINT中断信号,进程才会被唤醒,并处理信号,处理完信号后pause函数才返回,并继续运行该程序。

注:任何信号都可使pause唤醒。

 

  • sigsuspend函数:

   #include<signal.h>

   int sigsuspend(const sigset_t *sigmask);

   返回值:-1,并将errno设置为EINTR

 

sigsuspend函数和pause函数一样,可以是进程挂起(进入睡眠状态),直至有信号发生。

sigsuspend函数的参数是一个信号集,这个信号集是用来屏蔽信号的,信号集中存放了要屏蔽的信号。

如果该信号集为空的话,sigsuspend就不屏蔽任何信号,任何信号都可以使进程从挂起状态唤醒,这就与pause函数一样了。

 

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
 
void deal()
{
   printf(“信号干扰!\n”);
}
void main()
{
    sigset_tsigmask;
    sigemptyset(&sigmask);

    printf(“进程执行!\n”);
    signal(SIGINT,deal);
    sigsuspend(&sigmask);
    printf(“进程结束!\n”);
}

说明:

该例子与上面pause函数的例子是一样的。

  • sigsuspend与pause的不同处:

sigsuspend函数是pause函数的增强版。当sigsuspend函数的参数信号集为空信号集时,sigsuspend函数是和pause函数是一样的,可以接受任何信号的中断。但是,sigsuspend函数可以屏蔽信号,接受指定的信号中断。

sigsuspend函数=pause函数+指定屏蔽信号

注:信号中断的是sigsuspend和pause函数,不是程序代码。

sigsuspend是否影响sigprocmask屏蔽的信号呢?

影响!sigsuspend使原来的屏蔽信号全部失效,当sigsuspend返回,恢复原来的屏蔽信号。

  • sigsuspend什么时候使用?

     当我们的程序在进行一些业务处理的时候不想被一些信号所中断,我们就可以先屏蔽这些信号,在这个业务处理结束时我们可以使用sigsuspend函数处理在排队的信号(在这个过程中也可指定屏蔽的信号),处理完成后,在恢复之前的信号屏蔽,并处理下个业务处理。

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
void deal()
{
   printf("555555\n");
}
void main()
{
    sigset_t  sigs,sigmask;
    int  i;
    signal(SIGINT,deal);
    sigemptyset(&sigs);     //sigsuspend的信号集设置空,表示会sigsuspend会处
                             //理任何信号,如果想在处理排队的信号时屏蔽一些 
                             //信号,可以把相应的信号加到信号集中
    sigemptyset(&sigmask);
    sigaddset(&sigs,SIGINT);
    sigprocmask(SIG_BLOCK,&sigs,0); //屏蔽sigint信号,使其不能再业务处理过程
                                    //中干扰进程。
    for(i=0 ; i<5 ; i++)
    {
       printf("111111111\n");    //模拟业务处理
       sleep(1);
       printf("2222222\n");
       sigsuspend(&sigmask);       //处理正在排队的信号,处理信号完毕后,
                                   //sigsuspend函数才返回,并执行下个业务处理
       printf("333333333\n");    //模拟业务处理
       sleep(1);
       printf("44444444\n");
    }    
}

说明:在sigsuspend函数调用时,会使进程挂起(进入睡眠状态)等待信号的中断,如果没有信号发生,进程会一直挂起,当有信号发生时,但该信号不是sigsuspend函数的信号集中所设置的屏蔽的信号时,sigsuspend会处理该信号,当该信号处理完成后,sigsuspend函数才返回,并执行接下来的代码。

 

sigsuspend的整个原子操作过程为:


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

 

1.   sigpromask(SIG_UNBLOCK,&newmask,&oldmask)和
      sigpromask(SIG_SETMASK,&oldmask,NULL)区别

sigpromask(SIG_UNBLOCK,&newmask,&oldmask)

它的作用有两个:一是设置新的信号掩码(不阻塞newmask所指的信号集).二是保存原来的信号掩码(放在oldmask所指的信号集中)

sigpromask(SIG_SETMASK,&oldmask,NULL)
它的作用只有一个:设置新的信号掩码(信号掩码为oldmask所指的信号集)

 

2. sigsuspend 用实参 sigmask 指定的信号集代替调用进程的信号屏蔽, 然后挂起该进程直到某个不属于 sigmask 成员的信号到

达为止。此信号的动作要么是执行信号句柄,要么是终止该进程。
如果信号终止进程,则 suspend 函数不返回。如果信号的动作是执行信号句柄,则在信号句柄返回后,sigsuspend 函数返回,并使进程的信号屏蔽恢复到 sigsuspend 调用之前的值。

 

3. 清晰且可靠的等待信号到达的方法是先阻塞该信号(防止临界区重入,也就是在次期间有另外一个该信号到达),然后使用

sigsuspend 放开此信号并等待句柄设置信号到达标志。如下所示, 等待 SIGUSR1 信号到来:

sigemptyset(&zeromask);
sigaddset(&newmask, SIGUSR1);
......

sigprocmask(SIG_BLOCK, &newmask, NULL);
while(flag)
      sigsuspend(&zeromask);
flag = 0;
......
sigprocmask(SIG_UNBLOCK, &newmask, NULL);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值