2013-04-04 57 views
0

在下面的代码中,我有两个管道,其中一个是fd []将子范围变量传递给子进程。另一个管道rw []负责打印方法的结果。 FD正常工作,但RW打印垃圾。 range和narc_num都很长,我已经通过rw管道成功地打印了一个字符串和一个字符。有任何想法吗?谢谢。具有多个进程的管道输出错误

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <math.h> 
#include <string.h> 

/** 
* process propigating version of narcisstic base-10 number generator 
**/ 

/** 
* A Narcissistic number is a number where all of its digits, when raised to the power n where n is the number of digits in its number, equla the number itseld. 
* examples: 
* 2^1 = 2 
**/ 
void isNarcissisticNumber(int rw[], long min, long max){ 
// printf("min %ld max %ld\n", min, max); 
    long n; 
    for(n = min; n <= max; n++){ 
    long num = n; 
     int digits = floor(log10(num)) + 1; 
     int digit_arr[digits]; 
     long narc_num = 0; 
     int index = 0; 
     do{ 
      digit_arr[index++] = num%10; 
      num /= 10; 
     }while(num > 0); 
     index = 0; 
     for(index; index < digits; index++){ 
      narc_num += pow(digit_arr[index], digits); 
     } 
     if(narc_num == n){ 
     printf("%ld\n", n); 
     // parent: writing only, so close read-descriptor. 
     close(rw[0]); 
     write(rw[1], &n, sizeof(long)); 
       // close the write descriptor 
       close(rw[1]); 
    } 
    } 
} 

int main(int argc,   // Number of strings in array argv 
      char *argv[]){  // Array of command-line argument strings) 
    //check that there is only one passed in parameter in addition to the program name at argv[0] 
    if(argc != 2){ 
     printf("Args found: %d. 1 arg required\n", argc); 
     return; 
    } 
    //check that argv passed in is an int 
    if(!atoi(argv[1])){ 
     printf("argument shoud be the # of processes to proc.\n"); 
     return; 
    } 
    int num_processes = atoi(argv[1]); 
    //counter for narcissistic numbers 
    long offset = 10000; 
    long range= -offset; 
    //file pipe 
    int fd[2]; 
    //printing pipe 
    int rw[2]; 
    int n = 0; 
    long output; 
    while(n < num_processes){ // -1 offset to line up array index with num_processes arg 
    pipe(rw); 
    pipe(fd); 
     pid_t process = fork(); 
    pid_t child_process; 
     int status; 
    if(process == 0){ //chid process --> execute program 
     child_process = process; 
       /* Duplicate the input side of pipe to stdin */ 
     // chid: reading only, so close the write-descriptor 
      close(fd[1]); 
     read(fd[0], &range, sizeof(range)); 
     close(fd[0]); 
     isNarcissisticNumber(rw, range, range+offset-1); 
    }else if(process != 0){ 
     // parent: writing only, so close read-descriptor. 
      close(fd[0]); 
     range += offset; 
     write(fd[1], &range, sizeof(range)); 
     // close the write descriptor 
      close(fd[1]); 

     // for the current child process to complete its routine befire checking for output 
     wait(&child_process);  
     //read from the printing pipe 
     close(rw[1]); 
     while(read(rw[0], &output, sizeof(long))){ 
      printf("printer %ld\n", output); 
     } 
     close(rw[0]); 
    }else{ //failed to fork 
      printf("process failed to fork!\n"); 
      return -1; 
     } 
    n++; 
    } 
} 

编辑#1:而做出的父母只完成了一个孩子后检查,它不修复管道,这是现在只是甚至0中的printf否则显示的输出。

回答

1

我不确定这会解决所有的问题,但你肯定有一个逻辑问题。在你的计算程序中,你可以写入零或更长的长度到输出。在您的印刷(父母)例程中,您期望只有一个值能够通过。所以如果没有发送,你的阅读将失败。如果发送多个值,则只能读取第一个值。首先解决的办法是检查你的读取返回值,并在其上循环。

注意也可能 - 也许是一个好主意,等待()你的子进程。

+0

感谢提示,还没有,但我传递了一个char *进入管道,并从rw中取出。我在处理isNarccissistic()方法中的narc_num或n时会出现问题吗? – 2013-04-05 00:30:32

+0

完成读取操作后,您需要等待电话(不确定它会在此处产生多大影响) – DrC 2013-04-05 00:34:24

+0

另一项 - 在第一次写入后立即关闭rw [1]。所以你的剩余写入失败。此外,您将在同一地点多次关闭rw [0]。 – DrC 2013-04-05 00:39:42