简体   繁体   English

C 两个子进程向父进程发送信号,父进程回复

[英]C Two child process sending signal to parent, parent replies

I have a problem sending multiple signals to parent process in c.我在向 c 中的父进程发送多个信号时遇到问题。 I've been trying for a long time now and I still end up in a deadlock or a waitlock.我已经尝试了很长时间,但最终还是陷入了死锁或等待锁。 But I think it shouldn't be that complicated, I simply can't understand what is going on..但我认为它不应该那么复杂,我根本无法理解发生了什么......

So I have a parent process and two child processes.所以我有一个父进程和两个子进程。 The children are signaling to the parent, it accepts them, then sends a message to the children in pipe.孩子们向父母发出信号,它接受它们,然后向 pipe 中的孩子发送消息。 They write it out to console.他们把它写出来给控制台。

My code so far:到目前为止我的代码:

#include <stdio.h>
#include <signal.h>
#include <unistd.h> 
#include <sys/types.h>

void handler(int signumber) {
    printf("Signal with number %i has arrived\n", signumber);
}

int main() {


    signal(SIGUSR1, handler);
    signal(SIGUSR2, handler);

    int pipefd[2];
    char sz[100];
    if (pipe(pipefd) == -1)
    {
        perror("Pipe open error");
        exit(EXIT_FAILURE);
    }
    pid_t child, child2;
    child = fork();
    if (child > 0)
    {
        pause();
        printf("Signal1 arrived\n", SIGUSR1);

        //pause();
        printf("Signal2 arrived\n", SIGUSR2);

        close(pipefd[0]); //Usually we close unused read end
        write(pipefd[1], "Message", 13);
        printf("Pipe write complete\n");
        int status;
        waitpid(child2, &status, 0);
        waitpid(child, &status, 0);

        printf("Parent process ended\n");
    }
    else
    {
        child2 = fork();
            if(child2>0) //child 1
            { 
                printf(" child 1 Waits 3 seconds, then send a SIGTERM %i signal\n", SIGUSR1);
                sleep(3);
                signal(SIGUSR1, handler);
                close(pipefd[1]);  //Usually we close the unused write end
                printf("Child1 read start\n");
                read(pipefd[0], sz, sizeof(sz)); // reading max 100 chars
                printf("Child1 read end, Message: %s", sz);
                printf("\n");
                close(pipefd[0]); // finally we close the used read end
                printf("Child1 process ended\n");
                kill(child, SIGTERM);
            }
            else //child 2
            {
                printf("child 2 Waits 3 seconds, then send a SIGTERM %i signal\n", SIGUSR2);
                sleep(3);
                signal(SIGUSR2, handler);
                close(pipefd[1]);  //Usually we close the unused write end
                printf("Child2 read start\n");
                read(pipefd[0], sz, sizeof(sz)); // reading max 100 chars
                printf("Child2 read end, Message: %s", sz);
                printf("\n");
                close(pipefd[0]); // finally we close the used read end
                printf("Child2 process ended\n");
                kill(child2, SIGTERM);
            }
    }
    return 0;
}```

I think your code is laced with race conditions and memory errors.我认为您的代码带有竞争条件和 memory 错误。 You're also not sending SIGUSR1 or SIGUSR2 to the parent.您也没有将SIGUSR1SIGUSR2发送给父级。 Speaking subjectively, your solution is implemented in a manner is that is difficult to follow.主观地说,您的解决方案以一种难以遵循的方式实施。 If you ordered your statements differently, I think you'd also spot the same errors I'm seeing (I mention this later).如果你以不同的方式排列你的陈述,我想你也会发现我看到的同样的错误(我稍后会提到)。

I highly recommend starting small and building your way towards the goal you are aiming towards.我强烈建议从小处着手,朝着你的目标迈进。 Step 1, for instance, could be getting a process to fork, having the parent send a message over the pipe to the child, having the child exit and having the parent reap the child.例如,第 1 步可能是让进程分叉,让父进程通过 pipe 向子进程发送消息,让子进程退出并让父进程收割子进程。 In Step 2, add the signal handler you have in your example code above to the parent, only, and have the child send that signal (the exact signal the parent will handle) to the parent using kill() .在第 2 步中,仅将您在上面示例代码中的信号处理程序添加到父级,并让子级使用kill()将该信号(父级将处理的确切信号)发送给父级。 At some later step, add another fork call to create another child.在稍后的某个步骤中,添加另一个 fork 调用以创建另一个孩子。

As far as race conditions are concerned, your code is ordered such that after the first fork you have a parent process that is going to try to handle two child processes but only one child process has been created.就竞争条件而言,您的代码是这样排序的,这样在第一次fork之后,您有一个父进程将尝试处理两个子进程,但只创建了一个子进程。 Thus, you're trying to do something that is a no-no.因此,您正在尝试做一些禁止的事情。 Also, the first child is creating a second child.此外,第一个孩子正在创建第二个孩子。 This means the parent of the first child doesn't even know the second child exists because the first child has a completely different memory space.这意味着第一个孩子的父母甚至不知道第二个孩子的存在,因为第一个孩子有一个完全不同的 memory 空间。 The first child doesn't have a waitpid to wait for the second child that it created it because its "entry point" so to speak is after the waitpid call earlier in the code.第一个孩子没有等待它创建它的第二个孩子的waitpid ,因为它的“入口点”可以说是在代码前面的waitpid调用之后。

Also, beware of your write(pipefd[1], "Message", 13);另外,请注意您的write(pipefd[1], "Message", 13); is scary.很可怕。 The last parameter of write() is count . write()的最后一个参数是count You supplied 13 but the length of the string "Message" is less than 13 .您提供了13但字符串"Message"的长度小于13 The system call is going to spew garbage to the reader, causing more undesirable problems.系统调用将向阅读器吐出垃圾,导致更多不良问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM