我正在做一个操作系统课程的练习。为了学习使用信号(我的一个弱点),我想尝试只用信号同步N个进程。但是我做不到。
代码为:
# include "Header.h"
# include <signal.h>
// first sigHandler
void sigHandler(int signum)
{
printf("Received signal\n");
}
// second sigHandler
void sigHandler2(int signum)
{
printf("Received other signal\n");
}
int main(int argc, char *argv[])
{
// Number of process
int N = 2;
// Assign sigHandlers
signal(SIGUSR1, sigHandler);
signal(SIGUSR2, sigHandler2);
// array for pids to activate in order;
pid_t pid[N];
int i;
for (i = 0; i < N; i++)
{
// creation child
pid[i] = fork();
if (pid == 0)
{
// if is the last child, resume the father
if (i == N - 1)
{
kill(getppid(), SIGUSR2);
}
// expect SIGUSR1
pause();
printf("%i completed\n", getpid());
exit(0);
}
}
// expext that all child started
pause();
// active the last child
i--;
kill(pid[i], SIGUSR1);
signal(SIGUSR1, sigHandler);
// active other child
while (wait(NULL) != -1)
{
i--;
kill(pid[i], SIGUSR1);
signal(SIGUSR1, sigHandler);
}
printf("All fine\n");
exit(0);
}
我尝试用sleep(10)
替换pause()
系统,但结果是终端上出现四条“All fine”消息。
我猜想这个问题源于信号的异步特性,但我不知道如何解决它。
1条答案
按热度按时间whitzsjs1#
问题的主要部分是测试
if (pid == 0)
-数组地址不为空。您的意思是if (pid[i] == 0)
!通过这些更改以及使代码在我的默认编译选项(非常繁琐)下编译所需的最小更改,我从程序
sig79
中得到了以下输出:在调试问题时,我使用了这段代码,它有大量的打印内容(部分原因是我被有缺陷的测试弄糊涂了)。我使用等待循环是因为在某些情况下,您的父进程可能会有它没有创建的子进程--这些情况很模糊,但这段代码说明了这些情况。注意,子进程退出时的状态与子进程编号相对应;您可以在等待循环中报告的退出状态中看到这些数字。
有一次,当我运行程序(
sig59
)时,我得到了输出:并且,为了证明模糊情况可能发生:
forker
程序运行三个进程,每个进程依次运行exit 37
(十六进制0x 25),然后执行sig59
进程(它不知道它以前的子进程是forker
进程)。