#include <errno.h>
2 #include <signal.h>
3 #include "../../ourhdr.h"
4
5 void pr_mask (const char *str)
6 {
7 sigset_t sigset;
8 int errno_save;
9
10 errno_save = errno;
11 /*we can be called by signal handlers*/
12
13 if (sigprocmask (0, NULL, &sigset) < 0)
14 err_sys ("sigprocmask error");
15
16 printf ("%s/n",str);
17 if (sigismember (&sigset, SIGINT))
18 printf ("SIGINT/n");
19 if (sigismember (&sigset, SIGQUIT))
20 printf ("SIGQUIT/n");
21 if (sigismember (&sigset, SIGUSR1))
22 printf ("SIGUSR1/n");
23 if (sigismember (&sigset, SIGALRM))
24 printf ("SIGALRM/n");
25
26 /*remianing signals can go here*/
27
28 errno = errno_save;
29 }
1 #include <signal.h>
2 #include "../../ourhdr.h"
3
4 static void sig_int (int);
5
6 int main()
7 {
8 sigset_t newmask, oldmask, zeromask;
9
10 if (signal(SIGINT, sig_int) == SIG_ERR)
11 err_sys("signal (SIGINT) error");
12 sigemptyset(&zeromask);
13
14 sigemptyset(&newmask);
15
16 sigaddset (&newmask, SIGINT);
17 /*block SIGINT and save current signal mask*/
18
19 if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
20 err_sys("SIG_BLOCK error");
21
22 /*critocal region of code */
23 pr_mask("in critical region :");
24 sleep(4);
25
26
27 if (sigsuspend(&oldmask) != -1)
28 err_sys("sigsuspend error");
29 pr_mask("after return from sigsuspend");
30
31
32 if (sigprocmask (SIG_SETMASK, &oldmask, NULL) < 0)
33 err_sys("SIG_SETMASK error");
34 pr_mask("oldmask in proccess");
35
36 exit(0);
37 }
38
39
40 static void sig_int(int signo)
41 {
42 pr_mask("/nin sig_int:");
43 return;
44 }
sigsuspend 基本功能:
进程的信号屏蔽子设置为参数指向的值,在捕捉到一个信号或发生一个会终止该进程的信号之前,该进程被挂起
,如果捕捉到一个信号而且从该信号处理程序返回,则SIGSUSPEND返回,并且该进程的信号屏蔽子设置为调用SIGSUSPEND之前的值,
注意,此函数没有成功返回值,如果它返回到调用者,则总是返回-1 ,
这个程序这行结果
in critical region :
SIGINT
^C
in sig_int:
SIGINT
after return from sigsuspend
SIGINT
oldmask in proccess
这个结果可分析:
在程序调用sigprocmask期间,这个函数阻塞啦信号SIGINT,SLEEP(4)
在这4秒人内,SIGINT 信号是阻塞的茫然后过4秒
运行的是SIGSUSPEND这个函数解除啦对SIGINT 函数的阻塞,然后立即进入挂起状态,等待信号发生后从信号处理函数返回,
这样就体现出调用SIGSUSPENG函数的作用啦:这个函数是一个原子操作:
这样会避免在解除对SIGINT的阻塞和PAUSE之间发生的SIGINT信号被丢失的问题
/**********************************************************************************************************************/
sigsuspend的另一种应用是等待一个信号处理程序设置一个全局变量,下一个程序用于捕捉中断信号和退出信号 ,但是希望只有在捕捉到退出信号时再继续执行MAIN程序
#include <signal.h>
2 #include "../../ourhdr.h"
3
4 volatile sig_atomic_t quitflag = 1;
5 /* set nonzero by signal handler*/
6
7 int main()
8 {
9 void sig_int (int);
10 sigset_t newmask, oldmask, zeromask;
11
12
13 if (signal(SIGINT, sig_int) == SIG_ERR)
14 err_sys("signal SIGINT error");
15 if (signal(SIGQUIT, sig_int) == SIG_ERR)
16 err_sys("signal SIGQUIT error");
17
18 sigemptyset (&zeromask);
19
20 sigemptyset (&newmask);
21
22 sigaddset (&newmask, SIGQUIT);
23 /* block SIGQUIT and save current signal mask*/
24 if (sigprocmask (SIG_BLOCK, &newmask, &oldmask) <0)
25 err_sys("SIG_BLOCK error");
26
27 while (quitflag == 0)
28 sigsuspend(&zeromask);
29
30 /*SIGQUIT has been caught and is now blocked;do whatever*/
31
32 /* quitflag = 0; */
33 /*reset signal mask which unblocks SIGQUIT*/
34
35 if (sigprocmask (SIG_SETMASK,&oldmask, NULL) <0)
36 err_sys("SIG_SETMASK error");
37 exit(0);
38 }
39
40 void sig_int (int signo)
41 /*onr signal handlet for SIGINT and SIGQUIT*/
42 {
43 if (signo == SIGINT )
44 printf ("/niniterrupt/n");
45 else if (signo == SIGQUIT)
46 {
47 quitflag = 1;
48 printf ("hellow/n");
49 }
50 /*set flag for main loop*/
51
52 return;
53 }
-- 插入 --
这个程序比较关键的就是WHILE循环的设置:。
这里32 /* quitflag = 0; */这一行没明白是什么作用,求高手指点
因为把它注释掉对程序没有影响。