下面用刚学的几个函数做个实验。
example1
功能:每秒钟把各信号的未决状态打印一遍(阻塞了SIGINT信号,按Ctrl-C将会使SIGINT信号处于未决状态,按Ctrl-\仍可以终止程序)
step:
1) 调用函数sigprocmask可以读取或更改进程的阻塞信号集(又称信号屏蔽字)(目的是阻塞SIGINT信号);
2)调用sigpending读取当前进程的未决信号集,并将其打印。
程序如下:
程序运行时,每秒钟把各信号的未决状态打印一遍,由于我们阻塞了SIGINT信号,按Ctrl-C将会使SIGINT信号处于未决状态,按Ctrl-\仍然可以终止程序,因为SIGQUIT信号没有阻塞。
sigsuspend 函数
sigsuspend(const sigset_t *mask))用于等待接收某个信号,在接收到某个信号之前, 临时用mask替换进程的信号掩码, 并暂停进程执行,直到收到信号为止。sigsuspend 返回后将恢复调用之前的信号掩码。信号处理函数完成后,进程将继续执行。该系统调用始终返回-1,并将errno设置为EINTR。
注意:
sigsuspend的整个原子操作过程为:
(1) 设置新的mask阻塞当前进程 ;
(2) 收到信号,恢复原先mask;
(3) 调用该进程设置的信号处理函数 ;
(4) 待信号处理函数返回后,sigsuspend 返回。
实例:
功能描述:
sigsuspend 函数将进程的信号屏蔽字设置为 sigmask 指向的值。在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程被挂起。如果捕捉到一个信号而且从该信号处理程序返回,则sigsuspend返回,在返回之前,将进程的信号屏蔽字设置为调用sigsuspend之前的值。
用 法:
#
include < signal . h>
int sigsuspend ( const sigset_t * sigmask) ;
参 数:
sigmask: 指向信号集的指针,里面设置了屏蔽的信号
返回说明:
函数没有成功返回值。如果它返回到调用者,则总是返回-1,并将 errno 设置为EINTR(表示一个被中断的系统调用)。
example2:
功能:测试sigsuspend函数
step:
1)注册SIGINT和SIGQUIT的信号处理函数
2)设置信号屏蔽字(阻塞SIGQUIT)
3)通过sigsuspend函数和SIGQUIT来结束程序
我们运行程序(注释while(1);版本):
输入: ctrl+c : 输出 : interrept
输入: ctrl+c : 输出 : interrept
输入: ctrl+c : 输出 : interrept
输入: ctrl+c : 输出 : interrept
输入: ctrl+\ 程序终止
接着我们把程序中的while(1); 解除注释,运行程序
输入: ctrl+c : 输出 : interrept
输入: ctrl+c : 输出 : interrept
输入: ctrl+c : 输出 : interrept
输入: ctrl+c : 输出 : interrept
输入: ctrl+\ 没有反应
分析:
程序停在while(1)的时候,这里屏蔽了sigquit的信号,而程序在sigsuspend阻塞时候,把屏蔽信号设置成zeromask,不阻塞任何信号,所以能接受到ctrl+\