简体   繁体   中英

How a child process kill other child process and then terminate?

Here is the code, where parent process writes a string input in pipe and children processes read this from pipe. If child process reads from pipe the word "end", then i want to terminate all the processes and then terminate itself, and if reads the word "finish" i want to raise a signal to father for killing all the processes and then exit. I run the code and i had segmentation fault. Why it is wrong?

#define _POSIX_SOURCE
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
void measure_time(int sig)
{
    printf("child [%d] received signal %d\n", getpid(), sig);
}
int main(int argc, char *argv[])
{
    int n_task = 4;
    pid_t pid;
    pid_t pid_array[n_task];
    int fd[2];
    for (int i = 0; i < n_task; i++)
    {
        pid = fork();
        if (pipe(fd) == -1)
        {
            perror(" pipe ");
            exit(1);
        }
        if (pid < 0)
        {
            perror("fork");
            exit(1);
        }
        if (pid == 0) //child
        {
            char *buf;
            close(fd[1]);
            read(fd[0], buf, 10);
            printf("I read: %s", buf);
            if (strcmp(buf, "end") == 0)
            {
                for (int i = 0; i < n_task; i++)
                    kill(pid_array[i], SIGUSR1);
            }else if(strcmp(buf,"finish") == 0){
                /*Here i want father to kill all children and then exit.*/
            }
            exit(0);
        }
        close(fd[0]);
        char *buf;
        printf("Give the input string: \n");
        scanf("%s", buf);
        write(fd[1], buf, strlen(buf));
        close(fd[1]);
        pid_array[i] = pid;
    }
    sleep(1);
    for (int i = 0; i < n_task; i++)
        wait(NULL);
    return (0);
}

Besides the issue of uninitialized buf identified by @G. Sliepen, the pipe() need be called before fork() as file descriptors are kept open when forking child process(s). This is also how pipe works.

You can try to change your code snippet to put pipe() before fork() .

...
        if (pipe(fd) == -1)
        {
            perror(" pipe ");
            exit(1);
        }
        pid = fork();
        if (pid < 0)
        {
            perror("fork");
            exit(1);
        }
...

Please read the manual page of pipe(2) in which an example presented.

SO has this postfork() and pipes() in c explained this as well.

Update for terminating process(s)

This child process has no knowledge about existence of its siblings, but its parent process has. If not explicitly required, you can let the parent to do so, ie to "end" all child processes.

BTW, instead of sending signal SIGUSR1 it is better to send SIGTERM signal. Although SIGUSSR1 can cause the target process be terminated by default (see signal(7) ).

To "finish", ie to kill (or terminate) all the child processes as well as parent process, you can simplly kill the parent. All its descendants got killed as well. Or, you can send signal to the same process group. See kill(2) .

You are declaring a pointer buf , but did not initialize it. Subsequent calls to read() and scanf() will fail because the pointer is invalid.

You need to make sure buf is initialized and pointing to valid memory. A simple way to fix your code is to do:

char buf[10];
read(fd[0], buf, 10);

If you enable compiler warnings with -Wall , then the compiler will warn you about initialized variables.

Be aware of potential buffer overflows: if you declare char buf[10] , make sure you will never write more than ten bytes into it. Also, check the return value of functions like read() , write() , scanf() to ensure no errors were encountered, otherwise the contents of the buffers or output files might not be as expected.

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