进程信号的未决状态(pending status)
2012-10-04 21:07
513 查看
这两天看了apue有关进程信号的部分,觉得未决状态这个词很是不一般,呵呵。一开始当我看到这个词,我不理解,什么意思呢,读了好几遍。不知道是书里面讲的晦涩难懂,还是脑子越来越不行了,就是没有搞明白。后来看到后面的例子,然后再回想一下,终于清楚了!下面记录一下吧。
定义:信号产生和传递之间的时间间隔内,称此信号是未决的;
简单的说就是:一个已经产生的信号,但是还没有传递给任何进程,此时该信号的状态就称为未决状态。
未决状态信号的产生主要是因为进程对此信号的阻塞。例如为进程产生一个选择为阻塞的信号,而且对该信号的动作是系统默认动作或捕捉该信号,则为该进程将此信号保持为未决状态,直到该进程对此信号解除了阻塞或者对此信号的动作改为忽略。
我们知道,进程的信号屏蔽字规定了要阻塞传送到该进程的信号集。当产生了一个该进程已阻塞的信号,系统会为该进程生成一个信号集(其实该信号集是一直存在的,不是产生阻塞信号时才生成的),并将该阻塞的信号保存在此信号集中即将此信号集对应的信号置为未决状态。可以通过调用sigpending()来返回该信号集。
下面看一个apue上的例子:
执行上面的程序:
由上面程序的执行结果可以知道,当第一次sleep时,按下ctrl+\时产生SIGQUIT信号,由于进程对该信号已屏蔽,所以不会响应该信号,系统会把该信号保存起来,所以在调用sigpending()时,其中会有未决状态信号SIGQUIT。当对恢复进程的信号屏蔽字时,系统会把该未决信号发送给该进程,所以此时进程会调用信号处理函数输出:caught SIGQUIT。调用信号处理函数时,会终止进程的执行,当信号处理函数结束返回后,唤醒进程,最后输出:SIGQUIT unblocked。在最后sleep时,我又输入ctrl+\,因为上次捕捉到该信号时,已将此信号的处理方式设置成默认动作,所以这一次会直接退出。
Oct 4, 2012 21:31 @library
定义:信号产生和传递之间的时间间隔内,称此信号是未决的;
简单的说就是:一个已经产生的信号,但是还没有传递给任何进程,此时该信号的状态就称为未决状态。
未决状态信号的产生主要是因为进程对此信号的阻塞。例如为进程产生一个选择为阻塞的信号,而且对该信号的动作是系统默认动作或捕捉该信号,则为该进程将此信号保持为未决状态,直到该进程对此信号解除了阻塞或者对此信号的动作改为忽略。
我们知道,进程的信号屏蔽字规定了要阻塞传送到该进程的信号集。当产生了一个该进程已阻塞的信号,系统会为该进程生成一个信号集(其实该信号集是一直存在的,不是产生阻塞信号时才生成的),并将该阻塞的信号保存在此信号集中即将此信号集对应的信号置为未决状态。可以通过调用sigpending()来返回该信号集。
下面看一个apue上的例子:
#include <stdio.h> #include <signal.h> #include <unistd.h> //信号处理函数 static void sig_quit(int sigo) { printf("caught SIGQUIT...\n"); //将SIGQUIT信号的处理方式恢复成系统默认的处理动作 if(signal(SIGQUIT, SIG_DFL) == SIG_ERR) printf("can't reset SIGQUIT"); } int main() { sigset_t newmask, oldmask, pendmask; //定义对信号SIGQUIT的捕捉 if(signal(SIGQUIT, sig_quit) == SIG_ERR) { printf("can't catch SIGQUIT...\n"); return 0; } sigemptyset(&newmask);//清空信号集中所有要屏蔽的信号 sigaddset(&newmask, SIGQUIT);//将信号集中SIGQUIT信号设置为屏蔽 //保存进程旧的信号屏蔽字,并设置新的信号屏蔽字即使进程屏蔽SIGQUIT信号 if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) { printf("SIG_BLOCK error...\n"); return 0; } sleep(5); //返回阻塞的未决状态信号集 if(sigpending(&pendmask) < 0) { printf("sigpending error...\n"); return 0; } //判断在sleep期间是否有未决状态信号SIGQUIT产生 if(sigismember(&pendmask, SIGQUIT)) printf("\nSIGQUIT pending\n"); //恢复进程的信号屏蔽字 if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) { printf("SIG_SETMASK error...\n"); return 0; } printf("SIGQUIT unblocked\n"); sleep(5); return 0; }
执行上面的程序:
$ ./program ^\ \\按下ctrl+\ SIGQUIT pending caught SIGQUIT... SIGQUIT unblocked ^\ \\再次按下ctrl+\ 退出
由上面程序的执行结果可以知道,当第一次sleep时,按下ctrl+\时产生SIGQUIT信号,由于进程对该信号已屏蔽,所以不会响应该信号,系统会把该信号保存起来,所以在调用sigpending()时,其中会有未决状态信号SIGQUIT。当对恢复进程的信号屏蔽字时,系统会把该未决信号发送给该进程,所以此时进程会调用信号处理函数输出:caught SIGQUIT。调用信号处理函数时,会终止进程的执行,当信号处理函数结束返回后,唤醒进程,最后输出:SIGQUIT unblocked。在最后sleep时,我又输入ctrl+\,因为上次捕捉到该信号时,已将此信号的处理方式设置成默认动作,所以这一次会直接退出。
Oct 4, 2012 21:31 @library
相关文章推荐
- 进程信号的未决状态(pending status)
- 进程信号的未决状态(pending status)
- apue-手贱还是想谢谢信号未决pending
- 原来只有状态为'Ready'的进程才能收到信号
- linux:进程中信号的“3种状态 And 3张表”
- 4.3.3.3 master_status_event函数:父进程读status_fd管道,更新其记录的子进程状态
- 启动zookeeper时,jps显示有进程,但是status查看状态时就Error contacting service. It is probably not running
- 二十一、Linux 进程与信号---进程查看和进程状态、进程调度和进程状态变化、进程标识
- 信号、信号量、进程的状态的区别你知道吗?
- 进程信号三张表block,pending,handler
- cat /proc/$PID/status进程状态
- 僵尸进程学习 & 进程状态列表 & Linux信号学习
- 二十六、Linux 进程与信号---system 函数 和进程状态切换
- linux的父进程向子进程发kill信号例子以及对子进程的状态进行判断
- sigpending显示当前进程有哪个信号被pending
- 进程信号中的三大表格(block、pending、hardler)
- Linux进程状态
- linux系统进程状态查询命令--ps
- 信号注册函数回收子进程,waitpid非阻塞回收
- Win32状态(sc-win32-status)说明