简体   繁体   中英

C Two child process sending signal to parent, parent replies

I have a problem sending multiple signals to parent process in 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. 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. You're also not sending SIGUSR1 or SIGUSR2 to the parent. 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. 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() . At some later step, add another fork call to create another child.

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. 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. 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.

Also, beware of your write(pipefd[1], "Message", 13); is scary. The last parameter of write() is count . You supplied 13 but the length of the string "Message" is less than 13 . The system call is going to spew garbage to the reader, causing more undesirable problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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