パイプと子プロセスを扱う際にいくつか問題が発生しました。親と各子 パイプとフォークが間違った出力になります
- に必要
(フォークを使用して、4人の子を作成する)
- (パイプを用いて双方向通信を確立するには)数を含むファイルcard.txtからデータを読み出しますストリング
- の子1はAE、子2のGET BFなど
- 上の一個のメンバー変数を選択し得る、各子 ABCDEFGHにラウンドロビン方式で文字列を配布 - > SEを
$ ./a.out 1C < card.txt Child : 1, pid 1593 : <S2 S3 S9 ><H9 H6 HA H8 ><C6 CK ><D8 DQ D7 D3 > Child : 2, pid 1594 : <SA S6 S7 S4 ><H4 HJ H7 ><CQ C9 CT ><DT D2 D9 > Child : 3, pid 1595 : <SQ S5 ><H2 ><C7 C5 C8 CA C4 CJ C3 ><DA D5 > Child : 4, pid 1596 : <S8 SJ SK ST ><HK HT H5 H3 HQ ><C2 ><D4 D6 > child 1: H9 parent: child 1 played H9 child 2: CQ parent: child 2 played CQ child 3: H2 parent: child 3 played H2 child 4: HK parent: child 4 played HK
:ND
- 印刷を終了未使用の管を閉じるライトを使用して、親の変数()及び(読み取り)、ならびに近い()は期待出力される親プロセスに
を変数を受けただし、実際の出力は次のとおりです。
parent: child 1 played (null)parent: child 2 played (null)parent: child 3 played (null)parent: child 4 played (null)
なぜですか?どのように問題を解決するには?
コードは、この出力を作成しました:あなたはchild2_parent
とparent_child2
のような名前を使用して起動すると
#include <stdio.h>
#include <string.h>
#define BUFFERSIZE 51
int i=0;
int currpid, s;
char *buf[BUFFERSIZE];
char *array[BUFFERSIZE];
int n;
char *buffer[100];
/** child to parent pipe */
int child_parent[2];
/** parent to child pipe */
int parent_child[2];
/** child2 to parent pipe */
int child2_parent[2];
/** parent to child2 pipe */
int parent_child2[2];
/** child3 to parent pipe */
int child3_parent[2];
/** parent to child3 pipe */
int parent_child3[2];
/** child4 to parent pipe */
int child4_parent[2];
/** parent to child4 pipe */
int parent_child4[2];
void childFunction(){
int j;
for(i = s+1; i < BUFFERSIZE; i += 4)
{
buf[j] = array[i];
j++;
}
printf("\n<");
int r;
char *e;
for(r = 0; r < j; r++)
{
int index;
e = strchr(buf[r],'S');
if (e!=NULL){
index = (int)(e-buf[r]);
if (index == 0){
printf("%s ", buf[r]) ;
}
}
}
printf(">");
printf("<");
for(r = 0; r < j; r++)
{
int index;
e = strchr(buf[r],'H');
if (e!=NULL){
index = (int)(e-buf[r]);
if (index == 0){
printf("%s ", buf[r]) ;
}
}
}
printf(">");
printf("<");
for(r = 0; r < j; r++)
{
int index;
e = strchr(buf[r],'C');
if (e!=NULL){
index = (int)(e-buf[r]);
if (index == 0){
printf("%s ", buf[r]) ;
}
}
}
printf(">");
printf("<");
for(r = 0; r < j; r++)
{
int index;
e = strchr(buf[r],'D');
if (e!=NULL){
index = (int)(e-buf[r]);
if (index == 0){
printf("%s ", buf[r]) ;
}
}
}
printf(">\n");
switch (s){
case 0:
close(parent_child[1]);
close(parent_child[0]);
close(child_parent[0]);
buffer[0] = buf[0];
printf("child %d: %s", s+1, buffer[0]);
write(child_parent[1], &buffer[0], strlen(buffer[0]));
close(child_parent[1]);
break;
case 1:
close(parent_child2[1]);
close(parent_child2[0]);
close(child2_parent[0]);
buffer[0] = buf[0];
printf("child %d: %s", s+1, buffer[0]);
write(child2_parent[1], &buffer[0], strlen(buffer[0]));
close(child2_parent[1]);
break;
case 2:
close(parent_child3[1]);
close(parent_child3[0]);
close(child3_parent[0]);
buffer[0] = buf[0];
printf("child %d: %s", s+1, buffer[0]);
write(child3_parent[1], &buffer[0], strlen(buffer[0]));
close(child3_parent[1]);
break;
case 3:
close(parent_child4[1]);
close(parent_child4[0]);
close(child4_parent[0]);
buffer[0] = buf[0];
printf("child %d: %s", s+1, buffer[0]);
write(child4_parent[1], &buffer[0], strlen(buffer[0]));
close(child4_parent[1]);
break;
}
}
void parentFunction(){
switch (s){
case 0:
close(child_parent[1]);
close(parent_child[1]);
close(parent_child[0]);
read(child_parent[0],&buffer[0], sizeof(buffer[0]));
printf("parent: child %d played %s", s+1, buffer[0]);
close(child_parent[0]);
break;
case 1:
close(child2_parent[1]);
close(parent_child2[1]);
close(parent_child2[0]);
read(child2_parent[0],&buffer[0], sizeof(buffer[0]));
printf("parent: child %d played %s", s+1, buffer[0]);
close(child2_parent[0]);
break;
case 2:
close(child3_parent[1]);
close(parent_child3[1]);
close(parent_child3[0]);
read(child3_parent[0],&buffer[0], sizeof(buffer[0]));
printf("parent: child %d played %s", s+1, buffer[0]);
close(child3_parent[0]);
break;
case 3:
close(child4_parent[1]);
close(parent_child4[1]);
close(parent_child4[0]);
read(child4_parent[0],&buffer[0], sizeof(buffer[0]));
printf("parent: child %d played %s", s+1, buffer[0]);
close(child4_parent[0]);
break;
}
}
int main(int argc, char *argv[])
{
int ch;
ssize_t rread;
char *line = NULL;
size_t len = 0;
while (rread = getdelim(&line, &len, '\0', stdin) != -1) {
}
array[i] = strtok(line," ");
while(array[i]!=NULL)
{
array[++i] = strtok(NULL," ");
}
int childlimit = 4;
int childpids[childlimit];
int currpid;
if (pipe(child_parent) == 0 && pipe(parent_child) == 0 && pipe(child2_parent) == 0 && pipe(parent_child2) == 0 && pipe(child3_parent) == 0 && pipe(parent_child3) == 0 && pipe(child4_parent) == 0 && pipe(parent_child4) == 0)
{
for(s=0; s<childlimit; s++){
switch(currpid = fork()){
case 0:
printf("Child : %d, pid %d : ", s+1, getpid());
childFunction();
break;
case -1:
printf("Error when forking\n");
return 1;
default:
// in the father
childpids[s] = currpid;
parentFunction();
break;
}
}
//wait for all child created to die
waitpid(-1, NULL, 0);
}
}
あなたは '機能' と呼ばれるこれらの事を聞いたことがありますか?コードを明確にするのに便利です。メイン関数で子プロセスを処理するコードが多すぎます。プロセス管理を 'main()'にしておきます。文字列処理とI/O操作を、子プロセスでのみ実行される関数に委譲します。あなたは実際に子供の中で十分なファイル記述子を閉じているわけではありません。親がその子に書き込む必要がある場合は、親にあまりにも多くのファイル記述子をクローズしています。親が子どもに書き込む必要がない場合、なぜ親から子へのパイプで気になりますか? –
@ JonathanLeffler、コードを親と子のコードを別の関数に変更しました。私の実装では、子への親の書き込みが必要ですが、この時点では問題のためにまだ開発されていません。 –
関数のループ制御にグローバル変数 'i'を使用するのは災害です。グローバル変数が必要な場合もあります。グローバル変数が必要な場合は、それらを使用する必要があります。ほとんどの人は、そうではありません。そうでないときは、使用しないでください。一文字のグローバル変数名はあまり適切ではありません。 (これは、実行したように必要な各関数で 'i'の定義を繰り返すほうがはるかに優れています。)これにより、コードを非常に解析しにくくなります。あなたの文字列読み取りループは最後の '行'(ヌルで終了する '行')のみを保持します。私はそれが単一の操作でファイル全体をスラッピングする方法だと思います。 –