目标:使父进程计数器正确,counter1 = 5,counter2 =8。
程序应该创建 2 个子进程。它们中的每一个都会分别向父级发送一组数量的 SIGUSR1 和 SIGUSR2。分别是5次和8次。
为了简化,在多次崩溃导致我的系统注销、关闭所有程序并强制我登录之后,我改为打印有关父进程的信息。目标是将这些打印品替换为
kill(getppid(),SIGUSR1)
//和 SIGUSR2 用于第二个子进程。
当前子工作函数:
void childWork(int loopCounter, int sigNum)
{
for(; loopCounter>0; loopCounter--)
{
if(SIGUSR1==sigNum) //kill(getppid(),SIGUSR1);
printf("[%d] sending SIGUSR1 to %d\n", getpid(),getppid());
else if(SIGUSR2 == sigNum) //kill(getppid(), SIGUSR2);
printf("[%d] sending SIGUSR2 to %d\n", getpid(),getppid());
}
}
这是用于清理的僵尸处理函数:
void handleZombie(int sig) {
while (1) {
pid_t pid = waitpid(0, NULL, WNOHANG);
if (pid < 0) {
if (errno == ECHILD)
return;
printf("Error, cleaning\n");
}
if (pid == 0)
return;
}
最后是主要内容:
int main(int argc, char** argv)
{
printf("[%d] PARENT started! My parent: %d\n", getpid(), getppid());
childrenLeft=2;
setHandler(handleZombie,SIGCHLD);
setHandler(sigHandler1, SIGUSR1);
setHandler(sigHandler2, SIGUSR2);
int i;
for(i=1;i<=childrenLeft;i++)
{
pid_t pid = fork();
if(pid < 0)
printf("Error - fork\n");
if(pid==0)
if(i==1)
{
printf("[%d] child created!\n", getpid());
childWork(5,SIGUSR1);
}
if(i==2)
{
childWork(8, SIGUSR2);
printf("[%d] child created!\n", getpid());
}
exit(EXIT_SUCCESS);
}
printf("Work finished, final numbers:\nSIGUSR1 received: %d\nSIGUSR2 received: %d\n",sig1Count,sig2Count);
while (wait(NULL) > 0)
continue;
printf("[PARENT=%d] terminates\n", getpid());
return EXIT_SUCCESS;
}
当前的问题实际上是处理父进程。由于我不明白的原因,我的第二个 child 没有被创造。更重要的是,被打印的父项是出乎意料的。
[6025] PARENT started! My parent: 1300
[6026] child created!
[6026] sending SIGUSR1 to 6025
[6026] sending SIGUSR1 to 6025
[6026] sending SIGUSR1 to 6025
[6026] sending SIGUSR1 to 30404
[6026] sending SIGUSR1 to 30404
这是完整的输出。请帮助我了解这里发生了什么...
最佳答案
请注意,在 childWork()
返回之前,您不会报告子级 2 已创建。
但是,您的根本问题是在 if (pid == 0)
之后缺少语句分组大括号,这意味着在两次测试之后 exit(EXIT_SUCCESS):
if (i == 1)
和 if (i == 2)
;导致父级在启动第一个子级后立即退出。
int main(int argc, char** argv)
{
printf("[%d] PARENT started! My parent: %d\n", getpid(), getppid());
childrenLeft=2;
setHandler(handleZombie,SIGCHLD);
setHandler(sigHandler1, SIGUSR1);
setHandler(sigHandler2, SIGUSR2);
int i;
for(i=1;i<=childrenLeft;i++)
{
pid_t pid = fork();
if(pid < 0)
printf("Error - fork\n");
if(pid==0)
{ // Primary bug: braces missing
if(i==1)
{
printf("[%d] child created!\n", getpid());
childWork(5,SIGUSR1);
}
if(i==2)
{
printf("[%d] child created!\n", getpid()); // Moved before childWork()
childWork(8, SIGUSR2);
}
exit(EXIT_SUCCESS); // Only executed by children
} // Primary bug: missing braces
}
printf("Work finished, final numbers:\nSIGUSR1 received: %d\nSIGUSR2 received: %d\n",sig1Count,sig2Count);
while (wait(NULL) > 0)
continue;
printf("[PARENT=%d] terminates\n", getpid());
return EXIT_SUCCESS;
}
这是所需的最低限度的修复;还有许多其他可以而且也许应该做出的改变。
关于C 信号处理错误,发出子父联系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41536741/