我确信这是相当简单的事情,但对于我的生活,我无法弄清楚为什么我的子进程没有工作,等待,然后最后一个正在暂停(就像我没有正确关闭管道)。无论如何,我会发布一堆代码,但这就是它正在做的事情:
该程序解析一个 txt 文档并获取所有单个单词,并将它们沿管道循环样式发送到指定数量的子进程。我有一个一维数组,它保存管道 FD,每个偶数索引都是读取,每个奇数索引都是写入管道。
解析完成后,程序在分叉子级之前关闭读/写管道(关闭与父级的管道)。然后,在一个 for 循环中,产生指定数量的子进程,并在子进程中关闭相应管道的写入端,并打开读取端。fgets 必须用于从管道获取输入(我知道,烦人,但这是一个要求)。
子进程完成后,它会被父进程等待。有一些我试图帮助我的注释和调试器行,从它们看来,子进程似乎被分叉并正确输入,写管道关闭,读管道打开,但是当我这样做时fgets() 函数,它立即退出并由父级等待。有趣的是,并不是所有的孩子都得到等待。如果我希望孩子的数量为 3,则等待 2 个进程,第 3 个进程挂断。如果我想要 10 个进程,则等待 5 个进程,而第 6 个进程挂断。
所以,我很确定它与 fgets() 有关,但我不知道为什么!我有一种预感,这可能与换行符在沿管道发送时出现在错误的位置有关(fgets 一直读取到换行符,对吗?)但基于编写的代码和一些额外的调试语句,输入到来自父进程的管道似乎已正确终止换行符。
无论如何,这里是解析器的代码,然后是创建孩子的代码——
解析器:
char buf[PIPE_BUF];
int wordCount;
char buffer[PIPE_BUF];
char *temp;
char word[50];
FILE* inputFile = fopen(fileName, "r"); //OPENS file
//Parsing and distributing words round robin to pipes
while(fgets(buffer, (sizeof buffer), inputFile)){
//remove all non-alpha chars in buffer and converts to lowercase
int i;
for(i = 0; i < strlen(buffer); i++){
if(isalpha(buffer[i]) == 0){ //0 means it is not a letter
buffer[i] = ' ';
}
else{
buffer[i] = tolower(buffer[i]); //turn the current word to lower case
}
}
//parse words and sends them to the sort processes in a round-robin fashion
temp = strtok(buffer, " "); //splits along spaces
if(temp != NULL){
strcpy(word, temp);
strcat(word, "\n"); //puts newline at the end
}
int j = 0;
while(temp != NULL){
FILE *input = fdopen(pipefds[(j*2)+1], "w");
//close(pipefds[j*2]); //closing read pipes in parent
fputs(word, input); //puts into write pipe
printf("fputs done successfully with pipe %d with contents: %s\n", pipefds[(j*2)+1], word);
//close(pipefds[(j*2)+1]); //closing write pipe after write is done
temp = strtok(NULL, " ");
if(temp != NULL){
strcpy(word, temp);
strcat(word, "\n");
}
if(j == (numChildren - 1)){
j = 0;
}
else{
j++;
}
}
}
//need to close all parent writes, and parent reads (it's done with everything)
for(i = 0; i < numChildren; i++){
close(pipefds[i]);
}
父分叉和获取管道数据:
//Collection of children need to be created specified by numChildren
int count;
for(count = 0; count < numChildren; count++){
printf("Count: %d\n", count);
switch((p = fork())){
case -1:
perror("Could not create child");
exit(-1);
case 0:
printf("Entering child\n");
//child case, GET INPUT FROM PARENT TO SORT!!! SEND TO SUPPRESSOR (Uses both input and output)
//count[0] = read, count[1] = write
close(pipefds[(count*2)+1]); //closing write pipes in child
printf("write pipe closed in child\n");
FILE *output = fdopen(pipefds[count*2], "r"); //opening the read pipe from the parent write pipe
printf("read pipe opened in child\n");
fgets(buf, PIPE_BUF, output); //gets data from read pipe
printf("child read pipe contents read (fgets) with buf contents: %s\n", buf);
printf("child read pipe closed (%d)\n", getpid());
//execlp("sort", "sort", sortStuff,(char*)NULL);
close(pipefds[count*2]); //closing read pipe after reading is done
count = numChildren;
break;
default:
//parent case -- p holds pid of child
printf("I am the parent, PID: %d\n", getpid());
child = wait(&status);
printf("Waited on child %d\n", child);
break;
}
}
我提前为代码道歉,我不是最好的 C 程序员,所以事情往往会变得有点混乱。