其中一个子进程无法从管道中读取

Posted

技术标签:

【中文标题】其中一个子进程无法从管道中读取【英文标题】:One of the child processes can't read from pipe 【发布时间】:2020-02-17 09:40:45 【问题描述】:

我正在尝试在 C 中实现一个小型 IPC,但我有一个无法解决的问题。

我的主进程有两个孩子,孩子A和孩子B;孩子 A 首先被创建。 我有两个管道将信息传递给这些进程,pipefdpipefd2

首先,父进程读取文件的内容,并将这两个值写入两个管道:

1-length of the string 
2-string itself

一旦他们得到字符串的长度,他们就会创建一个给定长度的char数组,然后将字符串读入这个数组。

然后两个孩子都从他们的管道中读取。子 B 可以从管道中正确获取这些值,但子 A 的大小为 0。

这是我的代码,感谢您的宝贵时间!

输出:

Child A here, input read, size is: 0 
Size is 45169child reads input, size : 45169 
Child B here, input read, size is: 45169 


//
//  Created by Dilara on 16.02.2020.
//


#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>


#define MESSAGESIZE 10
#define READ_END    0
#define WRITE_END    1

int fsize(FILE *fp)
    int prev=ftell(fp);
    fseek(fp, 0L, SEEK_END);
    int sz=ftell(fp);
    fseek(fp,prev,SEEK_SET); //go back to where we were
    return sz;




void writeToPipe(int fd[2], char string[], long stell)
       close(fd[READ_END]);
        write(fd[WRITE_END], stell, sizeof(stell));
         write(fd[WRITE_END], string, strlen(string)+1);
         close(fd[WRITE_END]);


static void readFromPipe(int pipefd[2], char input[],long size)
         // wait(NULL);
           close(pipefd[WRITE_END]);
           read(pipefd[READ_END], input, size);
           printf("child reads input, size : %d \n",size);
           close(pipefd[READ_END]);


static long readSize(int pipefd[2])
       long size;
     close(pipefd[WRITE_END]);
     read(pipefd[READ_END], size, sizeof(size));
     printf("Size is %d",size);
     close(pipefd[READ_END]);
    return size;





int main()


    int pipefd[2];
    int pipefd2[2];
      int childA_pid;
      int childB_pid;

    if (pipe(pipefd) == -1)
           
               perror(" pipe");
               return 0;
           

    if (pipe(pipefd2) == -1)
           
               perror(" pipe");
               return 0;
           


       childA_pid = fork();

        if(childA_pid == 0)
            //childA

        long SIZE = readSize(pipefd);
        char input[SIZE];
        readFromPipe(pipefd, input, SIZE);
          printf("Child A here, input read, size is: %d \n",SIZE);

        
    else
        childB_pid = fork();
        if(childB_pid == 0)

             long SIZE = readSize(pipefd2);
             char input[SIZE];
             readFromPipe(pipefd2, input, SIZE);
              printf("Child B here, input read, size is: %d \n",SIZE);


        else
            //parent
               char *buffer;
                       FILE *fp = fopen("try.txt", "r");
                 if (fp != NULL)
                 
                     fseek(fp, 0L, SEEK_END);
                     long stell = ftell(fp);
                     rewind(fp);
                     char str[stell];
                     buffer = (char *)malloc(stell);

                     if (buffer != NULL)
                     
                         //fread(buffer, stell, 1, fp);

                             fread(str,stell,1, fp);
                          // printf("%s", str);
                         fclose(fp);
                         fp = NULL;
                         free(buffer);
                     

                       printf("SIZE: %d", stell);

                     writeToPipe(pipefd2, str,stell);
                     writeToPipe(pipefd, str,stell);



                 

        
   

    return 0;

【问题讨论】:

子 A 和子 B 的代码部分使用相同的数组 pipefd 您确定您现在正在显示您正在运行的实际代码吗?您仍然在为第二个 readSize(pipefd); 调用使用错误的管道。 @kaylum 用我正在运行的代码更新了整个代码。 您的read 呼叫错误。它没有传递size 变量的地址。应该是read(pipefd[READ_END], &amp;size, sizeof(size)); @kaylum 你说得对,我错过了。谢谢。我修复了它:但现在输出只是:SIZE:13766 【参考方案1】:
write(fd[WRITE_END], stell, sizeof(stell));

我认为您的代码在这里缺少与号。而不是 stell 变量,您应该使用它的地址:

write(fd[WRITE_END], &stell, sizeof(stell));

【讨论】:

是的,你是对的!我错过了,现在它正在工作。谢谢!

以上是关于其中一个子进程无法从管道中读取的主要内容,如果未能解决你的问题,请参考以下文章

C - 同时从两个管道(来自两个子进程的父进程)读取?

父进程无法读取来自 C 中 4 个不同管道的所有消息

linux c之通过管道实现兄弟间进程通信:

在 PySpark 中涉及带有管道的子进程的映射步骤失败

匿名管道:当子进程被杀死时,父进程中的 ReadFile 继续等待

python遍历目录就是这么简单