sigprocmask , sigpending 和 sigsuspend函数

转自  http://blog.csdn.net/elbort/article/details/7594772

sigprocmask函数:

功能描述:
设定对信号屏蔽集内的信号的处理方式(阻塞或不阻塞)。

用法:
#include <signal.h>

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

NOTE: If oldset is non-null, the previous value of the signal mask is stored in oldset.
参数:
how:用于指定信号修改的方式,可能选择有三种

SIG_BLOCK //加入信号到进程屏蔽。
SIG_UNBLOCK //从进程屏蔽里将信号删除。

SIG_SETMASK //将set的值设定为新的进程屏蔽。

相应函数命令:

sigset_t set

sigemptyset(&set) :清空阻塞信号集合变量

sigfillset(&set) :添加所有的信号到阻塞集合变量里

sigaddset(&set,SIGINT):添加单一信号到阻塞信号集合变量

sigdelset(&set,SIGINT):从阻塞信号集合变量中删除单一信号

sigismember(&set,int signum):这个函数测试信号signum是否包含在信号集合set中,如果包含返回1,不包含返回0,出错返回-1。错误代码也只有一个EINVAL,表示signum不是有效的信号代码。

代码说明:最简单的一个例子

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

int main()

{
        sigset_t set;             //定义阻塞信号集的变量
        sigemptyset(&set);        //清空变量set的阻塞信号
        sigaddset(&set,SIGINT);   //添加将要阻塞的信号"SIGINT"到阻塞信号集变量
        sigdelset(&set,SIGINT);   //从已有的阻塞信号集变量中删除阻塞信号"SIGINT"
        sigaddset(&set,SIGQUIT);  //添加将要阻塞的信号"SIGQUIT"到阻塞信号集变量
        sigprocmask(SIG_SETMASK,&set,NULL);// 将当前的阻塞信号集合变量set设置为该进程信号阻塞列表
        while(1);                 //
        return 0;
}

结果显示:

[[email protected] test1]$ ./test
^\^\
^C
[[email protected] test1]$

说明: ^\   键盘上是ctrl + \  对应信号 SIGQUIT

^c  键盘上是ctrl + c 对应信号 SIGINT

该结果说明test进程屏蔽了信号SIGQUIT,没有屏蔽信号SIGINT。

sigpending 函数:

功能:返回在阻塞期间接收到阻塞信号的集合。

代码说明:

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

int main( void )
  {
    sigset_t set, oset, pset;

sigemptyset( &set );
    sigaddset( &set, SIGINT );
    sigaddset(&set,SIGQUIT);
    sigaddset(&set,SIGABRT);
    sigprocmask( SIG_BLOCK, &set, &oset );
    printf( "Old set was %8.8ld.\n", oset );
    printf( "set is %8.8ld.\n", set );

sigpending( &pset );
    printf( "Pending set is %8.8ld.\n", pset );

kill( getpid(), SIGINT );
    sigpending( &pset );
    printf( "Pending set is %8.8ld.\n", pset );

kill( getpid(), SIGQUIT );
    sigpending( &pset );
    printf( "Pending set is %8.8ld.\n", pset );

kill( getpid(), SIGABRT );
    sigpending( &pset );
    printf( "Pending set is %8.8ld.\n", pset );

//    sigprocmask( SIG_UNBLOCK, &set, &oset );

if(sigismember(&pset,SIGINT) == 1)
    {
        printf("SIGINT was came.\n");
    }
    if(sigismember(&pset,SIGQUIT) == 1)
    {
        printf("SIGQUIT was came.\n");
    }
    if(sigismember(&pset,SIGABRT) == 1)
    {
        printf("SIGABRT was came.\n");
    }
    /* The program terminates with a SIGINT */
    return( EXIT_SUCCESS );
 }

运行结果:

[[email protected] test1]$ ./test2
Old set was 00000000.
set is  00000038.
Pending set is 00000000.
Pending set is 00000002.
Pending set is 00000006.
Pending set is 00000038.
SIGINT was came.
SIGQUIT was came.
SIGABRT was came.
[[email protected] test1]$

注意:红色那句去掉//会得到完全不同的结果。为什么??

//测试后,发现真的是

SIGINT was came.
SIGQUIT was came.
SIGABRT was came. 这三句话没有打印出来,不太好理解啊,sigprocmask( SIG_UNBLOCK, &set, &oset );这句话是去掉进程的信号屏蔽set,那么sigismember(&pset,SIGINT)这句&pset的信号屏蔽也是空?因为是针对相同的进程?暂且只能这么解释了.

sigsuspend函数

功能:它有一套属于自己的屏蔽信号mask,能够选择性接收某些信号。在接收到可行信号(也即是没有被屏蔽的信号)之前,运行到它时,它会一直悬挂着,有点类似pause()函数。接受到可行信号后,它会退出悬挂并执行相应的信号函数。接收到的信号源:1.之前运行sigprocmask()函数中阻塞的信号;2.悬挂后接受到的信号。

代码说明:

Example:sigsuspend (Correct Way to Wait for Single Signal)

sigset_tmaskall, maskmost, maskold;

intsignum = SIGUSR1;

sigfillset(&maskall);

sigfillset(&maskmost);

sigdelset(&maskmost,signum);

sigprocmask(SIG_SETMASK,&maskall, &maskold);

sigsuspend(&maskmost);

sigprocmask(SIG_SETMASK,&maskold, NULL);

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

具体例子说明:

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

void fun_int()
{
   printf("\nsigsuspend catch SIGINT\n");
   printf("The sigsuspend already restore the old mask for sigprocmask.Now still in the signal handle,next will sleep 5 seconds you can press ctrl-c to test\n");
   sleep(5);
   return;
}
int main()
{
        sigset_t        set;
        sigfillset(&set);
        signal(SIGINT,fun_int);
        sigprocmask(SIG_SETMASK,&set,NULL);
        sigdelset(&set,SIGINT);
        printf("Here is the sigprocmask signal block,before use sigsuspend\n");
        sleep(5);
        printf("\nsleep over,next is sigsuspend\n");
        sigsuspend(&set);
        printf("\nI have return from the handler.I will sleep 5 seconds You can press ctrl-c to send sigint to test the mask of SIGINT restore from sigsuspend for sigprocmask\n");
        sleep(10);
        printf("\nTest finish\n");
        return 0;
}

结果显示:

1.sigsuspend 接收信号来源为sigprocmask() block期间接收到的信号

[[email protected] test1]$ ./test
Here is the sigprocmask signal block,before use sigsuspend
^\^\^\
^C^C^C
sleep over,next is sigsuspend

sigsuspend catch SIGINT
The sigsuspend already restore the old mask for sigprocmask.Now still in the signal handle,next will sleep 5 seconds you can press ctrl-c to test
^C^C^C
I have return from the handler.I will sleep 5 seconds You can press ctrl-c to send sigint to test the mask of SIGINT restore from sigsuspend for sigprocmask
^C^C^C^\^\^\
Test finish
[[email protected] test1]$

2.sigsuspend 接收信号来源为线程进入悬挂后接收的信号

[[email protected] test1]$ ./test
Here is the sigprocmask signal block,before use sigsuspend
^\^\^\^\^\
sleep over,next is sigsuspend
^\^\^\^\^\
^C
sigsuspend catch SIGINT
The sigsuspend already restore the old mask for sigprocmask.Now still in the signal handle,next will sleep 5 seconds you can press ctrl-c to test
^C^C^C^C^C
I have return from the handler.I will sleep 5 seconds You can press ctrl-c to send sigint to test the mask of SIGINT restore from sigsuspend for sigprocmask
^C^C^C^C^C^\^\^\
Test finish
[[email protected] test1]$

时间: 2024-11-05 15:47:31

sigprocmask , sigpending 和 sigsuspend函数的相关文章

sigsuspend()函数

在学习sigsuspend()函数时存在一些迷惑,并不太理解书上所叙述的内容.最终,结合网上资源对该函数慢慢有了一点理解,记录下来,以备以后补充. 在<UNIX环境高级编程>中该函数的提出是在解除信号屏蔽(这里以SIGINT为例)时,信号立即发生,没有等待到pause函数执行的情况下. sigset_t newmask,oldmask;sigemptyset(&newmask);sigaddset(&newmask,SIGINT); if(sigprocmask(SIG_BLO

Linux进程间通信 -- 信号集函数 sigemptyset()、sigprocmask()、sigpending()、sigsuspend()

我们已经知道,我们可以通过信号来终止进程,也可以通过信号来在进程间进行通信,程序也可以通过指定信号的关联处理函数来改变信号的默认处理方式,也可以屏蔽某些信号,使其不能传递给进程.那么我们应该如何设定我们需要处理的信号,我们不需要处理哪些信号等问题呢?信号集函数就是帮助我们解决这些问题的. 有关Linux进程间使用信号通信的更多内容,可以参阅我的另一篇文章,Linux进程间通信 -- 信号量函数 signal().sigaction() 下面是信号函数集: 1.int sigemptyset(si

sigsuspend函数

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <signal.h> 5 #include <unistd.h> 6 void sigfunc(int signum); 7 int main() 8 { 9 int i; 10 sigset_t newsigset, oldsigset, pendsigset; 11 //1-设置捕获信号 12

sigsuspend sigprocmask函数的用法

一个进程的信号屏蔽字规定了当前堵塞而不能递送给该进程的信号集.调用函数sigprocmask能够检測或更改其信号屏蔽字,或者在一个步骤中同一时候运行这两个操作. #include <signal.h> int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset ); 返回值:若成功则返回0,若出错则返回-1 首先,若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回. 其次,若set是

sigsuspend sigprocmask函数的使用方法

一个进程的信号屏蔽字规定了当前阻塞而不能递送给该进程的信号集.调用函数sigprocmask可以检测或更改其信号屏蔽字,或者在一个步骤中同时执行这两个操作. #include <signal.h> int sigprocmask( int how, const sigset_t *restrict set, sigset_t *restrict oset ); 返回值:若成功则返回0,若出错则返回-1 首先,若oset是非空指针,那么进程的当前信号屏蔽字通过oset返回. 其次,若set是一个

函数指针,回调函数的定义和使用

一.函数指针 定义:函数指针是指向函数的指针变量,即本质是一个指针变量. int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func函数的首地址赋给指针f */ 指向函数的指针包含了函数的地址,可以通过它来调用函数.声明格式如下:  类型说明符 (*函数名)(参数)其实这里不能称为函数名,应该叫做指针的变量名.这个特殊的指针指向一个返回整型值的函数.指针的声明笔削和它指向函数的声明保持一致.指针名和指针运算符外面的括号改变了默认的运算符优先级.如果没有圆括

sigaction函数的使用

sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作). 他是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非POSIX系统上运行,那么就应该使用这个接口) 给信号signum设置新的信号处理函数act, 同时保留该信号原有的信号处理函数oldact int sigaction(int signo,const struct sigaction *restrict act, struct sigaction *restrict oact);

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

pause函数:       功能:让进程暂停直到信号出现   #include<unistd.h>      intpause();    函数说明:pause()会令目前的进程暂停(进入睡眠状态),直至信号(signal)所中断. 返回值:只返回-1. #include<stdio.h> #include<unistd.h> void deal() { printf(“信号干扰!\n”); } void main() { printf(“进程执行!\n”); sig

APUE读书笔记:关于sigsuspend

sigsuspend是一个原子操作,为了防止信号丢失而存在的,具体含义看下函数原型. int sigsuspend(const sigset_t *mask); 先忽略参数,sigsuspend完成的操作是阻塞进程的运行,直到有信号的产生.这样来看与另一个函数的作用相同.pause() 加上参数来理解,sigsuspend完成的操作是阻塞进程的运行,如果信号是mask参数设置的信号集,那么该信号是pending状态,而不会影响进程的阻塞状态,意思是进程仍然在阻塞中,直到不在信号集中的信号出现,进