sigpending

信号的阻塞:通过sigprocmask()将信号集sigset_t中的信号设置为阻塞。SIG_BLOCK是指对相应信号的“递送阻塞”,内核在递送一个原来被阻塞的信号给进程时(而不是在产生该信号时),才决定对它的处理方式,那么进程在信号递送给它之前仍可改变对该信号的动作。

一个信号的"生命周期"为:产生(generation)、未决(pending)、递送(delivery)

如果将信号设置为阻塞,那么,在信号产生和递送之间的时间间隔内,称信号是未决的(pending)。

如果信号被设置成阻塞,且该信号的动作是系统默认动作或捕获该信号,当该信号产生后,则进程将此信号的状态保持为未决(pending)状态,直到对该信号解除了阻塞或将该信号的动作改为忽略。

sigpending函数的作用是获取被设置为SIG_BLOCK的信号集。

1 static void sig_quit(int signo)
2 {
3     printf("111caught SIGQUIT\n");
4     if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
5     {
6         printf("can‘t reset SIGQUIT\n");
7     }
8 }
 1 int main(int argc, char** argv)
 2 {
 3     sigset_t newmask, oldmask, pendmask;
 4
 5     if (signal(SIGQUIT, sig_quit) == SIG_ERR)
 6     {
 7         printf("can‘t catch SIGQUIT\n");
 8         return -1;
 9     }
10
11     //block SIGQUIT and save cureent signal mask
12     sigemptyset(&newmask);
13     sigaddset(&newmask, SIGQUIT);
14
15     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//阻塞SIGQUIT信号
16     {
17         printf("SIGBLCOK error\n");
18         return -1;
19     }
20     printf("newmask:%x, oldmask:%x\n", newmask, oldmask);
21
22     sleep(5);
23
24     if (sigpending(&pendmask)<0)
25     {
26         printf("sigpending error\n");
27         return -1;
28     }
29     printf("pendmask:%x\n", pendmask);
30
31     if (sigismember(&pendmask, SIGQUIT))
32         printf("SIGQUIT pending\n");
33
34     if (sigprocmask(SIG_SETMASK, &oldmask, NULL))//解除阻塞
35     {
36         printf("sigprocmask error\n");
37         return -1;
38     }
39     printf("222SIGQUIT unblock\n");
40
41     sleep(5);
42
43     return 0;
44 }

运行结果为:

1. 当在第一个sleep 5s期间,Ctrl+\ 产生SIGQUIT信号时:

因为在sleep期间产生了SIGQUIT信号,那么此时该信号的状态时pending的,当该信号被设置为不阻塞后,即解除阻塞后,立即捕获该信号。从输出中可以看出,sig_quit中的printf语句先执行,然后再执行sigprocmask之后的printf语句。

2. 如果在第一个sleep 5s期间,不产生SIGQUIT信号,显然,sigpending的输出为0。

从结果中可以看到,本次pendmask为0,而上次pendmask为4。

SIG_BLOCK是指对相应信号的“递送阻塞”,内核在递送一个原来被阻塞的信号给进程时(而不是在产生该信号时),才决定对它的处理方式,那么进程在信号递送给它之前仍可改变对该信号的动作。

1 static void sig_quit(int signo)
2 {
3     printf("111caught SIGQUIT\n");
4     if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
5     {
6         printf("can‘t reset SIGQUIT\n");
7     }
8 }
1 static void sig_quit2(int signo)
2 {
3     printf("xxxcaught SIGQUIT\n");
4     if (signal(SIGQUIT, SIG_DFL)==SIG_ERR)
5     {
6         printf("can‘t reset SIGQUIT\n");
7     }
8 }
 1 int main(int argc, char** argv)
 2 {
 3     sigset_t newmask, oldmask, pendmask;
 4
 5     if (signal(SIGQUIT, sig_quit) == SIG_ERR)
 6     {
 7         printf("can‘t catch SIGQUIT\n");
 8         return -1;
 9     }
10
11     //block SIGQUIT and save cureent signal mask
12     sigemptyset(&newmask);
13     sigaddset(&newmask, SIGQUIT);
14
15     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//阻塞SIGQUIT信号
16     {
17         printf("SIGBLCOK error\n");
18         return -1;
19     }
20     printf("newmask:%x, oldmask:%x\n", newmask, oldmask);
21
22     sleep(5);
23
24     if (signal(SIGQUIT, sig_quit2) == SIG_ERR)
25     {
26         printf("can‘t catch SIGQUIT\n");
27         return -1;
28     }
29
30     if (sigpending(&pendmask)<0)
31     {
32         printf("sigpending error\n");
33         return -1;
34     }
35     printf("pendmask:%x\n", pendmask);
36
37     if (sigismember(&pendmask, SIGQUIT))
38         printf("SIGQUIT pending\n");
39
40     if (sigprocmask(SIG_SETMASK, &oldmask, NULL))
41     {
42         printf("sigprocmask error\n");
43         return -1;
44     }
45     printf("222SIGQUIT unblock\n");
46
47     sleep(5);
48
49     return 0;
50 }

运行结果为:

在line24中,又重新设置的SIGQUIT的信号处理程序。

如果信号被设置成阻塞,且该信号的动作是系统默认动作或捕获该信号,当该信号产生后,则进程将此信号的状态保持为未决(pending)状态,直到对该信号解除了阻塞或将该信号的动作改为忽略

 1 int main(int argc, char** argv)
 2 {
 3     sigset_t newmask, oldmask, pendmask;
 4
 5     if (signal(SIGQUIT, sig_quit) == SIG_ERR)
 6     {
 7         printf("can‘t catch SIGQUIT\n");
 8         return -1;
 9     }
10
11     //block SIGQUIT and save cureent signal mask
12     sigemptyset(&newmask);
13     sigaddset(&newmask, SIGQUIT);
14
15     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//阻塞SIGQUIT信号
16     {
17         printf("SIGBLCOK error\n");
18         return -1;
19     }
20     printf("newmask:%x, oldmask:%x\n", newmask, oldmask);
21
22     sleep(5);
23
24     if (sigpending(&pendmask)<0)
25     {
26         printf("sigpending error\n");
27         return -1;
28     }
29     printf("pendmask:%x\n", pendmask);
30
31     if (sigismember(&pendmask, SIGQUIT))
32         printf("SIGQUIT pending\n");
33
34     if (signal(SIGQUIT, SIG_IGN) == SIG_ERR)
35     {
36         printf("can‘t catch SIGQUIT\n");
37         return -1;
38     }
39     printf("SIGQUIT IGNORE");
40
41     sleep(5);
42
43     return 0;
44 }

运行结果为:

时间: 2024-11-09 10:15:02

sigpending的相关文章

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

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

10.13 sigpending函数

函数sigpending被阻塞发送并且当前被调用该函数的进程挂起的信号,这个信号集通过参数set返回. #include<signal.h> int sigpending(sigset_t*set); Returns:0if OK,-1 on error. Example #include"apue.h" staticvoid sig_quit(int); int main(void) { sigset_t newmask,oldmask,pendmask; if(sign

2信号处理之:信号产生原因,进程处理信号行为,信号集处理函数,PCB的信号集,sigprocmask()和sigpending(),信号捕捉设定,sigaction,C标准库信号处理函数,可重入函数,

 1信号产生原因 2.进程处理信号行为 manpage里信号3中处理方式: SIG_IGN SIG_DFL                                            默认Term动作 a signal handling function 进程处理信号 A默认处理动作 term   中断 core    core(调试的时候产生) gcc –g file.c ulimit –c 1024 gdb a.out core ign      忽略 stop     停止

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 sign

信号集、函数sigprocmask、sigpending

#include <signal.h> sigset_t set; //typedef unsigned long sigset_t int sigemptyset(sigset_t *set) // 将某个信号集清0 int sigfillset(sigset_t *set) // 将某个信号集置1 int sigaddsetset(sigset_t *set, int sino) // 将某个信号加入信号集 int sigdelset(sigset_t *set, int signo) /

Linux进程间通信总结

Linux进程间通信总结 1. 管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: (1)管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管道: (2)只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程): (3)单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中. (4)数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出

Linux信号、信号处理和信号处理函数

信号(signal)是一种软件中断,它提供了一种处理异步事件的方法,也是进程间惟一的异步通信方式.在Linux系统中,根据POSIX标准扩展以后的信号机制,不仅可以用来通知某种程序发生了什么事件,还可以给进程传递数据. 一.信号的来源 信号的来源可以有很多种试,按照产生条件的不同可以分为硬件和软件两种. 1.  硬件方式 当用户在终端上按下某键时,将产生信号.如按下组合键后将产生一个SIGINT信号. 硬件异常产生信号:除数据.无效的存储访问等.这些事件通常由硬件(如:CPU)检测到,并将其通知

Process Kill Technology &amp;&amp; Process Protection Against In Linux

目录 0. 引言 1. Kill Process By Kill Command 2. Kill Process By Resource Limits 3. Kill Process By Code Injection Into Running Process Via GDB 4. Kill Process By Using Cross Process Virtual Memory Modify 5. Kill Process By Using ptrace To Inject .so 6. P

Linux内核剖析 之 进程简介

1.概念 1.1  什么是进程? 进程是程序执行的一个实例,可以看作充分描述程序已经执行到何种程度的数据结构的汇集. 从内核观点看,进程的目的就是担当分配系统资源(CPU时间,内存等)的实体. 我们熟悉的fork()库函数,它有两种用法: (1).一个父进程希望复制自己,使父子进程执行不同的代码段,常用于网络服务程序. (2).一个进程要执行一个不同的程序,fork()后立即exec(),如shell. 1.2  什么是线程? 有时候,一个进程希望有多个执行流,如一款麻将游戏,三个由电脑控制的人