C 一个子进程如何杀死另一个子进程,然后终止?

C 一个子进程如何杀死另一个子进程,然后终止?,c,linux,pipe,fork,kill,C,Linux,Pipe,Fork,Kill,下面是代码,其中父进程在管道中写入字符串输入,子进程从管道中读取。如果子进程从管道中读取单词“end”,那么我想终止所有进程,然后自行终止,如果读取单词“finish”,我想向父进程发出一个信号,以终止所有进程,然后退出。我运行了代码,但出现了分段错误。为什么是错的 #define _POSIX_SOURCE #include <stdio.h> #include <errno.h> #include <unistd.h> #include <signa

下面是代码,其中父进程在管道中写入字符串输入,子进程从管道中读取。如果子进程从管道中读取单词“end”,那么我想终止所有进程,然后自行终止,如果读取单词“finish”,我想向父进程发出一个信号,以终止所有进程,然后退出。我运行了代码,但出现了分段错误。为什么是错的

#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);
}
#定义POSIX_SOURCE
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
无效测量时间(int sig)
{
printf(“子[%d]接收到信号%d\n”,getpid(),sig);
}
int main(int argc,char*argv[])
{
int n_task=4;
pid_t pid;
pid_t pid_数组[n_任务];
int-fd[2];
for(int i=0;i
您正在声明一个指针
buf
,但没有初始化它。对
read()
scanf()
的后续调用将失败,因为指针无效

您需要确保
buf
已初始化并指向有效内存。修复代码的简单方法是:

char buf[10];
read(fd[0], buf, 10);
如果使用
-Wall
启用编译器警告,则编译器将警告您初始化变量


注意潜在的缓冲区溢出:如果您声明
char buf[10]
,请确保您永远不会向其中写入超过十个字节的内容。另外,检查函数的返回值,如
read()
write()
scanf()
,以确保没有遇到错误,否则缓冲区或输出文件的内容可能不符合预期。

除了@G.Sliepen标识的未初始化
buf
问题之外,
管道()
需要在
fork()之前调用,因为在派生子进程时文件描述符保持打开状态。这也是管道的工作原理

您可以尝试将代码段更改为将
pipe()
放在
fork()
之前

。。。
如果(管道(fd)=-1)
{
佩罗(“管道”);
出口(1);
}
pid=fork();
if(pid<0)
{
佩罗尔(“福克”);
出口(1);
}
...
请阅读的手册页,其中提供了一个示例

这篇文章也解释了这一点

终止进程的更新

这个子进程不知道它的兄弟进程是否存在,但它的父进程知道。如果没有明确要求,您可以让父进程这样做,即“结束”所有子进程

顺便说一句,与其发送信号SIGUSR1,不如发送SIGTERM信号。尽管SIGUSSR1会导致目标进程在默认情况下终止(请参阅)


要“完成”,即杀死(或终止)所有子进程以及父进程,您可以简单地杀死父进程。它的后代也都被杀了。或者,您可以向同一进程组发送信号。看。

非常感谢。我更改了这个,但它确实有效。我认为这与孩子们在父母向管道中写入数据之前先读取数据这一事实有关。非常感谢。是的,你是对的,我改变了这个,但它仍然没有终止进程。
...
        if (pipe(fd) == -1)
        {
            perror(" pipe ");
            exit(1);
        }
        pid = fork();
        if (pid < 0)
        {
            perror("fork");
            exit(1);
        }
...