かなり単純なことだと思いますが、私の人生では、子プロセスが機能せず、待機し、最後のプロセスが一時停止している理由を理解できません(パイプを適切に閉じていないなど)。とにかく、私はたくさんのコードを投稿しますが、これはそれがしていることです:
プログラムはtxtドキュメントを解析し、すべての個々の単語を取得して、パイプラウンドロビンスタイルで指定された数の子プロセスに送信します。パイプFDを保持する1次元配列があり、すべての偶数インデックスが読み取りであり、すべての奇数インデックスが書き込みパイプです。
解析が終了した後、プログラムは子をフォークする前に読み取り/書き込みパイプを閉じます(親とのパイプを閉じるため)。次に、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プログラマーではないので、物事は少し厄介になる傾向があります。