【问题标题】:dup of anonymous pipe instead of stdout and passing arguments through it复制匿名管道而不是标准输出并通过它传递参数
【发布时间】:2021-03-15 10:28:26
【问题描述】:

问题: 我们创建了 2 个管道,父亲分叉并创建了一个孩子,将两个管道都传递给它。 父亲通过他的管道向孩子发送信息。 孩子收到后应该寄回去。 孩子应该使用库函数通过标准输出将其发送回: 问题出在这部分:

父母期望孩子使用 read 输出:

//READ FOR INT
            read(pipe_child_to_father[0], &number_recived, sizeof(int));
            printf("number recived: %d \n", number_recived);
    
        

孩子使用 printf 和 fflush 或 write 发送 iput 我在每一个上面评论了哪些有效,哪些无效

//---------------------------------SECTION WITH PROBLEM ------------------------
        //-------------------WITH INTS
        //WORKS
        write(STDOUT_FILENO,&number, sizeof(int)); 
        
        //NOT WORKING !!! sends wrong input
        printf("%d",number); 
        fflush(stdout);
        
        //NOT WORKING !! gets stuck waiting for input
        //printf("%d",number); 
        
        //NOT WORKING !!! sends wrong input
        fprintf(stdout, "%d", number);  
        fflush(stdout);
        

我也在底部粘贴完整的代码。

我得到的输出: 如果孩子使用 printf 向父亲发送数据(使用 fflush 清除缓冲区) - 数字应该相同!:

number sent :34461 
number recived: 909194548 
number sent :168284 
number recived: 842348086 
number sent :138440 
number recived: 909457719 
number sent :141832 
number recived: 909193265 

如果我不使用 fflush - 父亲会卡住等待输入....

几点说明:

  1. 这个帖子不是在寻求帮助来解决硬件问题。
  2. 这个问题是在部分任务中偶然发现的,我知道消息查询和命名管道之类的东西可能更适合这种工作,但我们应该只使用命名管道。

如果有人想复制粘贴完整的代码:

#include <stdlib.h> //for exit_succes
#include <stdio.h> // for prints
#include <unistd.h> //sleep for debug
#include <sys/types.h> // for pid_t
#include <errno.h>     //for perror
#include <signal.h>    //for signal
#include <time.h>

#define true  1
#define false 0
#define MAX_NUMBERS 2000
#define MAX_RND 200000
#define FATHER_RUNS 50



int iteri_search( int numbers[], int number);
void father_process();
void init_array(int array[]);
void kid(int array[], int pipe_recive[], int pipe_transmit[]);
void get_data(int pipe_father_to_bianry[], int pipe_binary_to_father[]);


int main (){
  
  father_process();


  
  exit(EXIT_SUCCESS);
}


void father_process(){
  
  pid_t pid;
  
  
  
  //setting array
  int array[MAX_NUMBERS];
  
  //initializing it
  init_array(array);
      
  //setting pipes 
  int pipe_father_to_child[2];
  int pipe_child_to_father[2];
  
  //Open all pipes
  if(pipe(pipe_father_to_child) == -1)
  {
      perror("Error");
      exit(EXIT_FAILURE);
  }
  
  if(pipe(pipe_child_to_father) == -1)
  {
      perror("Error");
      exit(EXIT_FAILURE);
  }   
  pid = fork();
      
      //first kid
  
  if(pid == 0)
  {
      kid(array,pipe_father_to_child, pipe_child_to_father);
  }
      
      

  
  ///close unwanted pipes for father
  close(pipe_child_to_father[1]);
  close(pipe_father_to_child[0]);

  
  get_data(pipe_father_to_child, pipe_child_to_father);
  
  
  
}


void get_data(int pipe_father_to_child[], int pipe_child_to_father[]){
  
  int index_of_run = 0;
  int number_recived = 0;
  double double_recived =0;

  
  while(index_of_run < FATHER_RUNS){
      

      int number = rand()%MAX_RND;    
      
      write(pipe_father_to_child[1], &number, sizeof(int));
      printf("number sent :%d \n", number);
      
      
      //SENDING THE INPUT ------------------------ THE PROBLEMATIC PART
      //READ FOR INT
      read(pipe_child_to_father[0], &number_recived, sizeof(int));
      printf("number recived: %d \n", number_recived);
      
      ++index_of_run;
  }
}



void kid(int array[], int pipe_recive[], int pipe_transmit[]){
  
  //will mesure time

  
  //close unwanted pipes
  close (pipe_recive[1]);
  close (pipe_transmit[0]);
  

  dup2(pipe_transmit[1],STDOUT_FILENO);

  int number = 0;
  
  int index =0;
  
  while(index < 50)
  {
      //get number from father
      read(pipe_recive[0], &number, sizeof(int));
  
      // turn on clock
      
      //---------------------------------SECTION WITH PROBLEM ------------------------
      
      //WORKS - correct output
      //write(STDOUT_FILENO,&number, sizeof(int)); 
      
      //NOT WORKING !!! sends wrong input as explained above
      //printf("%d",number); 
      //fflush(stdout);
      
      //NOT WORKING !! gets stuck waiting for input
      //printf("%d",number); 
      
      //NOT WORKING !!! sends wrong input as explained with printf
      //fprintf(stdout, "%d", number);    
      //fflush(stdout);
      
      
      
      ++index;

  }
  
  exit(EXIT_SUCCESS);
  
}


//initializing array with values
void init_array(int array[]){
  srand(17);
  int index;
  for(index = 0; index < MAX_NUMBERS; ++index){
      array[index] = rand();
  }
  
}

【问题讨论】:

  • 进程没有性别。与其说是“父亲”,不如说是“父母”。总是。
  • 您没有检查任何reads 或writes 返回的值。此外,您还注释掉了大部分代码。像“WORKS”或“NOTWORKING”这样的评论并不是特别具有描述性。哪个代码到底做了什么?我们是否应该猜测应该撤消哪些 cmets?
  • dup2(x,y) 之后,您通常会使用close(x) 以避免有2 个描述符副本。
  • 看来你问题的根源是write(1, &amp;number, sizeof number)printf("%d", number)之间的区别。但我不确定“不工作!!!发送错误输入”的实际含义。
  • @WilliamPursell 我编辑了这个问题。我希望它现在更清楚。请告诉我。

标签: c linux operating-system pipe


【解决方案1】:

我怀疑还有很多其他问题,但你肯定需要处理这个:

char * buff = NULL;
...
read(pipe_child_to_father[0], &buff, sizeof(buff));
 

您没有通过管道写入地址。由于您正在尝试读取由 %d 的 printf 格式字符串生成的值,因此您几乎肯定需要类似以下内容:

char buf[32];
...
rc = read(pipe_child_to_parent[0], buf, sizeof buf);

【讨论】:

  • 正在使用:read(pipe_child_to_father[0], &amp;number_recived, sizeof(int)); 还不够吗?它应该从输入中读出 int 的大小。
  • 如果您使用“%d”将整数打印为字符串,则大于 9999 的值将不适合 4 字节值。如果整数是 8 个字节,那么你会遇到大于 99999999 的值的问题。但是如果你读取一个字符串并尝试将其视为一个 int,你会得到意想不到的输出。
  • 哦,我想我现在明白了。所以printf 将其转换为str,这就是为什么它被接收为str。所以唯一的方法是将 at 作为字符串接收,将 atoi 接收为整数,或者通过 write 命令发送。
猜你喜欢
  • 2021-05-18
  • 2017-05-11
  • 1970-01-01
  • 2022-07-05
  • 1970-01-01
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多