在下面的代码中,我有两个管道,一个,fd []句柄将一个范围变量传递给子进程。另一个管道rw []负责打印方法的结果。 fd工作正常,但是rw打印垃圾。范围和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:虽然这使得父项仅在子项完成后进行检查,但它不会修复管道的输出,即使printf另有说明,它现在只是0。
答案 0 :(得分:1)
我不确定这会解决所有问题,但你肯定有一个逻辑问题。在计算例程中,您可以向输出写入零个或多个长整数。在您的打印(父)例程中,您只需要一个值。因此,如果没有发送任何内容,您的阅读将失败。如果发送了多个值,则只读取第一个值。第一个修复方法是检查读取的返回值并在其上循环。
另请注意 - 在您的子进程上等待()可能也是一个好主意。