可以用信号实现父、子进程之间的同步

来源:互联网 发布:诸暨市淘宝司法拍卖 编辑:程序博客网 时间:2024/05/19 03:25

可以用信号实现父、子进程之间的同步,这是信号应用的另一个实例。

程序清单10-17包含了8.9节提到的五个例程的实现,它们是:TELL_WAIT、TELL_PARENT、TELL_CHILD、WAIT_PARENT和WAIT_CHILD。

        《UNIX环境高级编程》P272:程序清单10-17 父子进程可用来实现同步的例程(有改动)

?
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
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
 
static volatile sig_atomic_t    sigflag;
static sigset_t    newmask, oldmask, zeromask;
 
static void sig_usr(int signo)
{
    sigflag = 1;
}
 
void TELL_WAIT(void)
{
    if (signal(SIGUSR1, sig_usr) == SIG_ERR)
        fprintf(stderr, "signal(SIGUSR1) error\n");
    if (signal(SIGUSR2, sig_usr) == SIG_ERR)
        fprintf(stderr, "signal(SIGUSR2) error\n");
 
    sigemptyset(&zeromask);
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGUSR1);
    sigaddset(&newmask, SIGUSR2);
 
    // 添加 SIGUSR1 和 SIGUSR2,保存当前信号屏蔽字
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
        fprintf(stderr, "SIG_BLOCK error\n");
}
 
void TELL_PARENT(pid_t pid)
{
    kill(pid, SIGUSR2);                // 通知父进程,准备完毕
}
 
void WAIT_PARENT(void)
{
    while (sigflag == 0)
        sigsuspend(&zeromask);        // 等待父进程
    sigflag = 0;
 
    // 恢复原来的信号屏蔽字
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
        fprintf(stderr, "SIG_STEMASK error\n");
}
 
void TELL_CHILD(pid_t pid)
{
    kill(pid, SIGUSR1);                // 通知子进程,准备完毕
}
 
void WAIT_CHILD(void)
{
    while (sigflag == 0)
        sigsuspend(&zeromask);        // 等待子进程
    sigflag = 0;
 
    // 恢复原来的信号屏蔽字
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
        fprintf(stderr, "SIG_SETMASK error\n");
}

        其中使用了两个用户定义的信号:SIGUSR1由父进程发送给子进程,SIGUSR2由子进程发送给父进程。

0 0