C 信号处理错误,发出子父联系

标签 c linux signals fork

目标:使父进程计数器正确,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/

相关文章:

c - Scanf 接受 EOF 之前的数字(不以空格分隔)

c - sysTick 频率操纵?

linux - 在 Ubuntu 上使用 virtualbox 在 vagrant 上设置 nginx 配置时出错

c - while 循环中的 raise()

c - 具有不同const限定的指针的结构之间的兼容性

C循环双链表: rev traverse gives different list-pointer address for same node

ruby-on-rails - 无法在 Linux 上安装 Rails : “Failed to build gem native extension” with ruby 2. 3

linux - 如何使用 GIMP 编写自定义自动裁剪脚本?

linux - glibc 和系统调用被信号中断

c - 如何在不更改其值的情况下获取先前设置的闹钟的剩余时间?