【发布时间】:2020-06-07 06:55:49
【问题描述】:
我有一个程序从随机访问文件中读取,并返回文件中的最小和最大数字。一个要求是使用 fork() 和管道传输结果通过 4 个进程完成。我将文件分成 4 个块,并让每个进程评估文件的一个块。我找到每个块的最大值和最小值并将它们写入管道。最后,我将比较管道值并找到最大值和最小值。
当管道返回 -1 时,我无法读取管道。关于我做错了什么的任何见解?谢谢!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int findMin(int start, int end, const char * filename);
int findMax(int start, int end, const char * filename);
//Calculates minimum and maximum of a number
int main(int argc, char * argv[])
{
const char * filename; // name of file to read
FILE * ft; // file handle for the file
int pid, // process id of this process
num, // the number of integer values in the file
i, // loop control variable for reading values
temp=0; // used to store each value read from the file
long size; // size in bytes of the input file
/*********************************************************************/
filename = argv[1]; // read the file named on the command line
ft= fopen(filename, "rb");
if (ft)
{
pid = getpid();
fseek (ft,0,SEEK_END); //go to end of file
size = ftell(ft); //what byte in file am I at?
fseek (ft,0,SEEK_SET); //go to beginning of file
num = (int)size / (int)sizeof(int); // number of integer values
printf("file size: %li bytes\n", size);
printf("sizeof(int) = %i bytes\n",(int) sizeof(int));
printf("how many integers = %i\n\n", num);
fclose(ft);
}
//Split file size into quarters to make 4 processes
int increment = num/4;
int num1 = increment;
int num2 = num1 + increment;
int num3 = num2 + increment;
int num4 = num;
int status;
int pid1 = -1;
int pid2 = -1;
//Pipes
int fdmin1[2];
int fdmax1[2];
int fdmin2[2];
int fdmax2[2];
int fdmin3[2];
int fdmax3[2];
int fdmin4[2];
int fdmax4[2];
//initializing pipes
if(pipe(fdmin1) == -1)
{
perror("Piping fd1 failed");
return 0;
}
if(pipe(fdmax1) == -1)
{
perror("Piping fd2 failed");
return 0;
}
if(pipe(fdmin2) == -1)
{
perror("Piping fd3 failed");
return 0;
}
if(pipe(fdmax2) == -1)
{
perror("Piping fd4 failed");
return 0;
}
if(pipe(fdmin3) == -1)
{
perror("Piping fd3 failed");
return 0;
}
if(pipe(fdmax3) == -1)
{
perror("Piping fd4 failed");
return 0;
}
if(pipe(fdmin4) == -1)
{
perror("Piping fd3 failed");
return 0;
}
if(pipe(fdmax4) == -1)
{
perror("Piping fd4 failed");
return 0;
}
//temp variables for pipes
int temp1;
int temp2;
int temp3;
int temp4;
int temp5;
int temp6;
int temp7;
int temp8;
pid1 = fork();
printf("pid1: %d \n", pid1);
if(pid1 > 0)
{
//Process 1
temp1 = findMin(0, num1, filename);
temp2 = findMax(0, num1, filename);
close(fdmin1[0]);
if(write(fdmin1[1], &temp1, sizeof(int)) == -1)
{
printf("Error writting to pipe");
}
close(fdmin1[1]);
close(fdmax1[0]);
if(write(fdmax1[1], &temp2, sizeof(int)) == -1)
{
printf("Error writting to pipe");
}
close(fdmax1[1]);
}
else if(pid1 == 0)
{
//Process 2
temp3 = findMin(num1, num2, filename);
temp4 = findMax(num1, num2, filename);
close(fdmin2[0]);
if(write(fdmin2[1], &temp3, sizeof(int)) == -1)
{
printf("Error writting to pipe");
}
close(fdmin2[1]);
close(fdmax2[0]);
if(write(fdmax2[1], &temp4, sizeof(int)) == -1)
{
printf("Error writting to pipe");
}
close(fdmax2[1]);
pid2 = fork();
printf("pid2: %d \n", pid2);
if(pid2 > 0)
{
//Process 3
temp5 = findMin(num2, num3, filename);
temp6 = findMax(num2, num3, filename);
close(fdmin3[0]);
if(write(fdmin3[1], &temp5, sizeof(int)) == -1)
{
printf("Error writting to pipe");
}
close(fdmin3[1]);
close(fdmax3[0]);
if(write(fdmax3[1], &temp6, sizeof(int)) == -1)
{
printf("Error writting to pipe");
}
close(fdmax3[1]);
}
else if(pid2 == 0)
{
//Process 4
temp7 = findMin(num3, num4, filename);
temp8 = findMax(num3, num4, filename);
close(fdmin4[0]);
if(write(fdmin4[1], &temp7, sizeof(int)) == -1)
{
printf("Error writting to pipe");
}
close(fdmin4[1]);
close(fdmax4[0]);
if(write(fdmax4[1], &temp8, sizeof(int)) == -1)
{
printf("Error writting to pipe");
}
close(fdmax4[1]);
}
}
//Close all pipe ends in all processes
close(fdmin1[0]);
close(fdmin1[1]);
close(fdmin2[0]);
close(fdmin2[1]);
close(fdmin3[0]);
close(fdmin3[1]);
close(fdmin4[0]);
close(fdmin4[1]);
close(fdmax1[0]);
close(fdmax1[1]);
close(fdmax2[0]);
close(fdmax2[1]);
close(fdmax3[0]);
close(fdmax3[1]);
close(fdmax4[0]);
close(fdmax4[1]);
//Wait for all processes to finish
int returnStatus;
waitpid(pid1, &returnStatus, 0);
int returnStatus2;
waitpid(pid2, &returnStatus2, 0);
//Make sure we are in parant process
if(pid1 > 0)
{
//Variables to compare min and max returned from processses
int min1;
int max1;
int min2;
int max2;
int min3;
int max3;
int min4;
int max4;
//read from pipe (error is occuring here)
close(fdmin1[1]);
if(read(fdmin1[0], &min1, sizeof(int)) == -1)
{
printf("Error reading");
}
close(fdmin1[0]);
printf("min1: %d \n", min1);
}
return 0;
}
//function to find the minimum in the file
int findMin(int start, int end, const char * filename)
{
int temp;
int smallestNum;
int i;
int length = end - start;
FILE * ft2;
ft2= fopen(filename, "rb");
fseek (ft2,start,SEEK_SET);
fread(&smallestNum,sizeof(int),1,ft2);
for(i = 0; i < length; i++)
{
fread(&temp,sizeof(int),1,ft2);
//printf("%d \n", temp);
if(temp < smallestNum)
{
smallestNum = temp;
}
/*
printf("%5i: %7i ",pid,temp);
if ((i+1)%5 == 0)
printf("\n");
*/
}
fclose(ft2);
printf("SmallestNum: %d \n", smallestNum);
return smallestNum;
}
//function to find maximum in file
int findMax(int start, int end, const char * filename)
{
int temp;
int largestNum;
int i;
int length = end - start;
FILE * ft3;
ft3= fopen(filename, "rb");
fseek (ft3,start,SEEK_SET);
fread(&largestNum,sizeof(int),1,ft3);
for(i = 0; i < length; i++)
{
fread(&temp,sizeof(int),1,ft3);
//printf("%d \n", temp);
if(temp > largestNum)
{
largestNum = temp;
}
/*
printf("%5i: %7i ",pid,temp);
if ((i+1)%5 == 0)
printf("\n");
*/
}
fclose(ft3);
printf("Largest Num: %d \n", largestNum);
return largestNum;
}
这是生成随机访问文件的代码
/*
* This file generates a binary output file containing integers. It
* requires the output filename as a parameter and will take an
* argument indicating the number of values to generate as input.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define BIAS 0 // a bias value added to the numbers to "bias" the file
// contents to provide an offset to the min and max
int main(int argc, char * argv[]) {
const char * filename; // name of the output file
FILE * ft; // file handle for output file
int numtogen = 1000000; // default is to generate 1,000,000 numbers
int randomnum, i; // variables used in the loop generating numbers
if (argc<2) { // not enough arguments, need output file name
printf("Usage: gendata <filename> [number of numbers]\n");
return 1;
}
if (argc == 3) // optional third argument for number of numbers
numtogen = atoi(argv[2]);
filename=argv[1]; // use the filename entered to store numbers
srand(time(NULL)); // seed the random number generator
ft= fopen(filename, "wb") ;
if (ft) {
for (i = 0; i < numtogen; i++){
randomnum = rand() % numtogen + BIAS;
fwrite(&randomnum,sizeof(int),1,ft);
}
fclose(ft);
}
return 0;
}
【问题讨论】: