2017-04-15 9 views
0

パイプに対するユーザーの読み取り/書き込み権限があります。グループは読んだ。他は読んだ。しかし、プログラムを実行すると、プログラムが「固まった」状態になります。プログラム1は「親」です。プログラム2は「子供」です。名前付きパイプはCプログラムで開けません

プログラム1:

int main(int argc, char * argv[]) 
{ 
FILE *fptr; //for opening and closing input file 
int fdw;// write to pipe; 
int fdr; //read to pipe; 
pid_t pid; 
int inputarray[500]; 
int arraylength = 0; int j =0; 
char *mypipe = "mypipe"; 


if (argc < 2) 
{ 
    printf("Need to provide the file's name. \n"); 
    return EXIT_FAILURE; 
} 
//open input file 
fptr = fopen(argv[1], "r"); 
if (fptr==NULL) 
{ 
    printf("fopen fail.\n"); 
    return EXIT_FAILURE; 
} 

//read input file and fill array with integers 
while (!feof(fptr)) 
{ 
    fscanf(fptr,"%d",&inputarray[arraylength]); 
    arraylength = arraylength + 1; 

} 

fclose(fptr); //close input file 



pid = fork(); 

mkfifo(mypipe, 0666); 
fdw = open("mypipe",O_WRONLY); 
if (fdw < 0) 
{ 
    perror("File can't open to write."); 
    return; 
} 
int b; 
b=3; 
write(fdw,&b,sizeof(b)); 
close(fdw); 




if (pid ==-1) 
{ 
perror("fork"); 
exit(1); 
} 
int status; //exit status of child 

if(pid==0)//if child process 
{ 
    execl("program2", (char*) NULL); 
} 

else //if parent process 
{ 
wait(&status);} 
if((WIFEXITED(status))) 
{ 
printf("Child's exit code %d", WEXITSTATUS(status)); 
} 
else{ 
printf("Child did not terminate with exit");} 



} 

プログラム2:プログラムは読まれて書いているものまで、FIFOへの書き込みをブロックします

int fdl; 
int data; 
fdl = open("mypipe",O_RDONLY); 
if (fdl < 0) 
{ 
    perror("File can't open to read."); 
    return; 
} 
read(fdl,&data,sizeof(data)); 
close(fdl); 
+0

いつになってしまうのですか? – thrig

+0

プログラム1が停止します。それは親です。プログラム2は子供です。 – Alex

+0

あなたはこれをすべて1つのプログラムで行うことができることを知っていましたか?プログラム1のexecはprogram2の内容に置き換えることができます。 –

答えて

1

。子プロセスでの読み取りは、execl()まで行われないため、の書き込み後には発生しません。

また、実際には両方のプロセスがfork()からfifoへの書き込みを試み、すぐに書き込みを開始するように見えます。

fork()を入力し、返されたPIDをテストします。子供がexecl()に電話をしている間、親はfifoに書き込むべきです。 fifoplは、fork()コールの前に親によって作成される必要があります。

またそれを正しく読んで容易になり、バグ(忘れられた中括弧など)を公開することがあなたのコードを、フォーマットするindentclang-formatを使用して検討すべきです。


単純な完全なサンプルプログラムです。親は子供に文字列を書き込み、子供が文字でそれを文字を読み込み、標準出力に出力します。両方の子と親プロセスが同じ状況にあるので、私が使用している可能性があり、この場合、

#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <sys/wait.h> 
#include <unistd.h> 

void parent(void); 
void child(void); 

int main(void) { 
    pid_t pid; 

    mkfifo("myfifo", 0666); /* fails if exists, but we don't care here */ 

    if ((pid = fork()) < 0) 
    abort(); 

    if (pid == 0) 
    child(); /* will not return */ 
    else 
    parent(); 

    return EXIT_SUCCESS; 
} 

void parent(void) { 
    int fd; 
    int len; 
    int ret; 
    int stat; 

    char *ptr; 
    char *msg = "Hello World!"; 

    if ((fd = open("myfifo", O_WRONLY)) < 0) 
    abort(); 

    len = strlen(msg) + 1; 
    ptr = msg; 

    puts("Parent: About to write to child"); 

    while ((ret = write(fd, ptr, len)) != 0) { 
    if (ret > 0) { 
     len -= ret; 
     ptr += ret; 
    } else 
     abort(); 
    } 

    close(fd); 

    puts("Parent: Waiting for child to exit"); 
    wait(&stat); 

    printf("Parent: Child exited with status %d\n", stat); 
} 

void child(void) { 
    int fd; 
    int ret; 

    char ch; 

    if ((fd = open("myfifo", O_RDONLY)) < 0) 
    abort(); 

    puts("Child: About to read from parent"); 

    while ((ret = read(fd, &ch, 1)) != 0) { 
    if (ret > 0) 
     putchar(ch); 
    else 
     abort(); 
    } 
    putchar('\n'); 

    close(fd); 

    puts("Child: I'm done here"); 
    exit(EXIT_SUCCESS); 
} 

pipe()で作成された匿名パイプのペアですが、これは名前付きパイプの作成を含むフローを示しています。

+0

親は待機呼び出し後または前にパイプに書き込む必要がありますか? – Alex

+0

@Alexの前に。子が終了すると 'wait()'が返ります。 'write()'は子供が 'read()'するまでブロックします。 – Kusalananda

+0

私はfork()の前にパイプを作成していますが、write()はwait()の後ですがまだスタックしていません。 – Alex

関連する問題