【问题标题】:Trouble getting child processes to communicate with each other无法让子进程相互通信
【发布时间】:2019-10-28 17:08:55
【问题描述】:

我是 linux 编程的新手。我正在尝试生成两个子进程并通过管道连接它们。生成子进程应该生成随机数,而另一个子进程应该运行一个二进制文件,该二进制文件接受这两个数字并找到它们的最大公约数。二进制文件已经很好地与标准输入一起工作,所以我试图将它重定向到读取管道的末端。同样,我通过将标准输出连接到管道的写入端来生成进程。

但我认为我没有做好将它们连接在一起的工作,因为没有输出。任何帮助将不胜感激!

我没有在网上找到很多资料,所以建议这些资料也会有很大帮助。谢谢。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

#define exec_path "nsd"

void create_pipe(int *proc_pipe);

int create_proc();

void sig_handler(int sig);

int main() {
    int proc_pipe[2];
    pid_t gen_proc;
    pid_t nsd_proc;
    int proc_stat;

    create_pipe(proc_pipe);

    gen_proc = create_proc();

    if (gen_proc == 0) {
        // child exec
        struct sigaction act;
        act.sa_handler = &sig_handler;

        close(proc_pipe[0]);
        dup2(proc_pipe[1], 1);
        close(proc_pipe[1]);

        while (1) {
            printf("%d %d\n", rand() % 4096, rand() % 4096);
            sleep(1);
            if (sigaction(SIGTERM, &act, NULL) == -1) exit(2);
        }
    } else {
        nsd_proc = create_proc();

        if (nsd_proc == 0) {
            // child exec
            close(proc_pipe[1]);
            dup2(proc_pipe[0], 0);
            close(proc_pipe[0]);

            execl(exec_path, "nsd", (char *) NULL);
        } else {
            close(proc_pipe[0]);
            close(proc_pipe[1]);
            sleep(5);
            kill(gen_proc, SIGTERM);
            wait(&proc_stat);
            if (proc_stat != 0) {
                perror("ERROR");
                return 1;
            } else {
                printf("OK\n");
                return 0;
            }
        }
    }
}

void sig_handler(int sig) {
    if (sig == SIGTERM) {
        perror("GEN TERMINATED");
        exit(0);
    }
}

pid_t create_proc() {
    pid_t pid = fork();
    if (pid == -1) {
        perror("error forking new process");
        exit(2);
    }
    return pid;
}

void create_pipe(int *proc_pipe) {
    if (pipe(proc_pipe) == -1) {
        perror("failed to create pipe");
        exit(2);
    }
}

【问题讨论】:

  • perror 消息通常不以换行符结尾,因为“首先(如果 s 不是 NULL 并且 *s 不是空字节 ('\0')),参数字符串 s 是打印,后跟一个冒号和一个空格。” (man7.org/linux/man-pages/man3/perror.3.html)
  • gen_proc = create_proc(); nsd_proc = create_proc();:这两行创建了 3 个进程。第二行由父级执行一次,子级在第一行创建一次。
  • “nsd”是当前目录中的可执行文件吗?
  • @user253751 是的,它在当前目录中
  • @IngoLeonhardt 好吧​​,我移动了父分支中的第二个分叉以避免不必要的分叉。现在编辑代码以供进一步检查。 nsd_proc 仍然没有输出。

标签: c linux io pipe fork


【解决方案1】:

printf 在填充缓冲区之前不会调用 write。您没有给您的孩子足够的时间来填充该缓冲区。在孩子睡觉之前添加fflush(stdout),这样一些数据实际上会写入管道。

【讨论】:

    猜你喜欢
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    相关资源
    最近更新 更多