C - 在不同的过程中使用不同的管端

标签 c linux pipe system-calls dup2

我一直在搜索和阅读手册,但仍然无法了解管道机制。我正在制作一个程序,它应该执行以下操作:

  1. 父进程创建管道,两个子进程并等待。

    1. 第一个 child 生成一对随机数,并通过管道将它们之间的空格传递给第二个进程。它一直持续到 从 parent 那里得到信号。
    2. 第二个 child 重定向它的输入,因此它是第一个 child 的输出,并将输出重定向到 out.txt 文件。然后执行 已经编译的程序,从 (1) 计算数字的 GCD;
  2. parent 关闭管道并杀死 child 。

所以我得到了这个 C 代码(我减少了它以便帖子符合规则):

const int PIPE_READEND=0;
const int PIPE_WRITEEND=1;

        (...)
if (child1 == 0) {
        //Child1 code here
        close(fd[1]);

        struct sigaction sa;
        sa.sa_handler = sigHandler;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;
        if (sigaction(SIGUSR1,&sa,NULL) == -1){ //Handling SIGUSR1 signal
            perror("Signal handling unexpected error");
            exit(errno);
        }
        int a,b;
        srand(time(&t));
        if (dup2(fd[PIPE_READEND],1) < 0){ //Redirecting stdout to the pipe fd.
            perror("In Child1 Redirecting stdout to pipe error");
            exit(errno);
        } 
        close(fd[0]);
        while(1){
            a = rand();
            b = rand();
            printf("%d %d\n", a, b);
            sleep(1);
        }


       (...)
if ((child2 = fork()) < 0){
        perror("Fork error in Child2 process");
        exit(errno);
    } else if (child2 == 0){
        //Child2 code here
        close(fd[PIPE_READEND]);
        FILE *outfile = fopen("out.txt","w");
        dup2(fd[PIPE_WRITEEND],0); 
        dup2(outfile,1); 
        close(fd[PIPE_WRITEEND]);
        execl("c1/main","main",(char *)NULL);   

问题是,执行后,out.txt 保持为空。我对管道数组索引感到失望,哪个用于什么。

最佳答案

您从错误的管道索引写入和读取。您需要更改它们:

这会将标准输出重定向到管道输入。

   close(fd[0]);
   dup2(fd[1], STDOUT_FILENO);

这会将管道输出重定向到标准输入。

   close(fd[1]);
   dup2(fd[0], STDIN_FILENO);

另外 dup2 接受整数,而不是指针,所以你应该这样做:

   f = fopen("out.txt", "w");
   dup2(fileno(f), STDOUT_FILENO);

关于C - 在不同的过程中使用不同的管端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41029398/

相关文章:

c - 将两个结构传递给 C 中的回调函数的更优雅的方法

c - 寻找优化此代码的方法

c - int main() 和 void main() 是如何工作的?

linux - 令人困惑的 Makefile

java - 如何使用 upstart 正确启动 gradle 生成的脚本?

C++ 我想将两个字符串写入管道,两者之间有一个小的延迟

c - 新Linux内核的epoll是否还存在惊群问题?

linux - 在命令行 Git 中编辑不正确的提交消息

java - 管道文件消失但仍然有效

bash - 终止 shell 脚本而不等待管道的早期部分