APUE学习--信号(3)

来源:互联网 发布:mysql分布式数据库搭建 编辑:程序博客网 时间:2024/05/20 03:39

1、信号集

本篇文件介绍信号集的概念。信号集就是一些信号的集合,类型是sigset_t,这个类型是不透明的,当然可以找到头文件仔细研究但意义不大。该类型所涉及的操作函数如下:

[cpp] view plaincopy
  1. int sigemptyset(sigset_t *set);  //初始化信号集set为空,不包含任何信号  
  2. int sigfillset(sigset_t *set);  //初始化信号集set为满,包含所有信号  
  3. int sigaddset(sigset_t *set, int signo);  //为set信号集中增加signo信号  
  4. int sigdelset(sigset_t *set, int signo);  //为set信号集中减去signo信号  
  5. int sigismember(const sigeset_t *set, int signo); //判断set是否有信号signo  
这些操作非常简单,唯一需要注意的是当使用一个信号集变量前,sigemptyset()是必须的。

信号集的作用是方便对其中的信号做统一的处理(避免一个一个信号做处理带来的麻烦)。第一个应用是信号屏蔽字,屏蔽字本身就是用信号集描述的。

每个进程(线程)都拥有一个信号屏蔽字,信号屏蔽字中的信号不会到来,注意的一点是信号屏蔽字屏蔽的并非是信号的接受而是阻塞信号的传递,也就是说信号屏蔽字中的信号如果产生了,会在传递阶段阻塞直到接触该信号的屏蔽。设置信号屏蔽字的函数式sigprocmask()

[cpp] view plaincopy
  1. int sigprocmask(int how, const sigset_t  *set, sigset_t *oldset);  

参数how,阐明了要进行的操作,包括:

SIG_BLOCK增加阻塞(或操作),该进程新的信号屏蔽字是其当前信号屏蔽字和set指向信号集的并集。set包含了我们希望阻塞的附加信号。

SIG_UNBLOCK减少阻塞,该进程新的信号屏蔽字是其当前信号屏蔽字和set所指向信号集补集的交集。set包含了我们希望解除阻塞的信号。

SIG_SETMASK设置屏蔽字(赋值操作),该进程新的信号屏蔽字将被set指向的信号集的值代替。

参数set是设置的信号集;参数oset是获得设置前的信号屏蔽字。如果参数set传NULL,则不会改变屏蔽字,仅仅具有获得屏蔽字的功能。

注意:1.不屏蔽信号的接受而是阻塞信号的传递,解除阻塞后信号会到来(信号没有丢失而是未处理),在解除阻塞前被阻塞的信号称为未决信号,该信号的状态称为未决状态。

2.fork()时子进程会继承父进程的信号屏蔽字,但之后父子进程的信号屏蔽字互不影响

3.不能阻塞信号SIGKILL SIGSTOP(这两个信号不能更改处理动作),如果set中有这两个信号,sigprocmask也不会处理这个信号(不返回出错)

4.不应该阻塞SIGPIPE这样的信号,因为这些信号是由于程序出错而产生的

5.在一个信号的处理函数执行过程中,该信号会自动加入到屏蔽字中。

刚刚提到未决信号的概念,某一时刻可以有很多的未决信号,这样就构成了未决信号集,可以通过下面的函数获得:

[cpp] view plaincopy
  1. int sigpending(sigset_t *set);  
set是一个出参,获得后可以通过sigismember(set, signo)来检查有没有signo信号处于未决状态。只能判断有没有不能获得有多少个(不可靠只能有一个,可靠可能有多个)

刚才提到,在信号处理函数中,该信号会自动加入到信号屏蔽字中,当处理函数执行结束后才会解除阻塞。那如果在处理函数执行过程调用了longjmp()跳转出处理函数,那该信号不会从信号屏蔽字中去掉,那么该信号会用于阻塞,解决办法是之前提到过的sigsetjmp() siglongjmp(),它们相较于setjmp()和longjmp()增加了保存屏蔽字的功能,在跳转时会恢复屏蔽字。

有时,我们需要等待某一个信号的到来,但pause()函数会被所有信号打断,为了达到这种目的,方法是将别的可能到来的信号加入到屏蔽字中然后等待特定的信号,当信号到达后,再解除那些增加到屏蔽字中的信号的屏蔽。连续使用sigprocmask->pause->sigprocmask可以实现,也可以使用sigsuspend()函数

[cpp] view plaincopy
  1. int sigsuspend(const sigset_t *sigmask);  

功能是用sigmask替换当前的信号屏蔽字,挂起等待信号,恢复调用前的屏蔽字。




0 0
原创粉丝点击