apue_78信号sigsuspend

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/* Filename: susp.c
* No.78.信号sigsuspend
* Description:
* 1.屏蔽信号
* 2.打印5个*换行后
* 3.取消信号屏蔽并且等信号
* 4.收到信号后回到1
* Last modified: humble 20200404 17:12
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#define _SAVESET_ (1)

#define demo (2) //0,1,2

static void usage(void);

void int_handler(int i)
{
write(1, "!", 1);
}

int main(int argc, char **argv)
{
int i;
sigset_t set, oset, saveset;

if(argc != 1){
fprintf(stderr, "argc !=1");
usage();
exit(1);
}

signal(SIGINT, int_handler);
sigemptyset(&set);
sigaddset(&set, SIGINT);

#if _SAVESET_
//此句目的在于保存当前mask到saveset,方便以后恢复,用SIG_UNBLOCK或SIG_BLOCK都无所谓
sigprocmask(SIG_UNBLOCK, &set, &saveset);
#endif

#if (demo == 1) || (demo == 2)
sigprocmask(SIG_BLOCK, &set, &oset); //block住
#endif

while(1){
#if (demo == 0)
sigprocmask(SIG_BLOCK, &set, &oset);
#endif

for(i = 0; i < 5; i++)
{
write(1, "*", 1);
sleep(1);
}
write(1, "\n", 1);

#if (demo == 0)
sigprocmask(SIG_SETMASK, &oset, NULL);
//因为sigprocmask和pause两个函数不原子
//如果在sigprocmask和pause之间收到信号,那响应完信号之后进入了pause
//可是我们期望它响应信号后能继续打印*
pause();
#elif (demo == 1)
sigset_t tmpset;
sigprocmask(SIG_SETMASK, &oset, &tmpset); //恢复unblock,并用tmpset记录block集(set和tmpset相同)
//sigprocmask和pause两个函数不原子,结果跟demo0一样
pause();
sigprocmask(SIG_SETMASK, &tmpset, NULL); //再次block
#elif (demo == 2)
//sigsuspend 就相当于上面demo1的原子操作
sigsuspend(&oset);//原子化 unblock后立刻进入pause(wait)
#endif
}

#if _SAVESET_
//把mask设置为saveset(相当于恢复了之前的状态)
sigprocmask(SIG_SETMASK, &saveset, NULL);
#endif

return 0;
}

static void usage(void)
{
#define USAGE "Usage:\n\
Helloworld\n"
printf(USAGE);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# li @ evpower in ~/humble/tmp/lhq/parallel/signal on git:master x [10:39:27]
$ make susp #demo1
cc susp.c -o susp

# li @ evpower in ~/humble/tmp/lhq/parallel/signal on git:master x [10:39:31]
$ ./susp
*****^C
!^C!*****
^\[1] 35672 quit (core dumped) ./susp

# li @ evpower in ~/humble/tmp/lhq/parallel/signal on git:master x [10:40:23] C:131
$ vi susp.c

# li @ evpower in ~/humble/tmp/lhq/parallel/signal on git:master x [10:40:23] C:131
$ make susp #demo2
cc susp.c -o susp

# li @ evpower in ~/humble/tmp/lhq/parallel/signal on git:master x [10:40:43]
$ ./susp
*****^C
!****^C^C^C^C*^C^C^C^C^C^C
!*^C****
!**^\[1] 35836 quit (core dumped) ./susp

# li @ evpower in ~/humble/tmp/lhq/parallel/signal on git:master x [10:41:11] C:131
$