2017-04-15 1 views
0

J'ai des autorisations de lecture/écriture sur un canal. Le groupe a lu. L'autre a lu. Mais le programme est "bloqué" quand je le lance. Le programme 1 est le "parent". Le programme 2 est "l'enfant".Le tube nommé ne s'ouvre pas dans le programme C

Programme 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");} 



} 

Programme 2:

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

Quel programme est bloqué quand? – thrig

+0

Le programme 1 est bloqué. C'est le parent. Le programme 2 est l'enfant. – Alex

+0

Saviez-vous que vous pouvez faire cela en un seul programme: L'exec, dans le programme 1, peut être remplacé par le contenu de programme2. –

Répondre

1

Le programme bloque sur l'écriture au PEPS jusqu'à ce qu'il écrit est en cours de lecture. La lecture dans le processus enfant ne se produira pas puisque le execl() n'arrive pas avant après l'écriture.

En outre, il semble que les deux processus essaieront réellement d'écrire sur le FIFO puisque vous fork() et que vous commencerez immédiatement à écrire.

Vous devez fork(), puis tester sur le PID renvoyé. Le parent devrait alors écrire au fifo pendant que l'enfant devrait appeler execl(). Le fifo doit être créé par le parent avant l'appel fork().

Vous devez également utiliser indent ou clang-format pour formater correctement votre code, ce qui facilite la lecture et peut exposer des bogues (accolades oubliées, etc.).


Un exemple de programme complet simple. Le parent écrit une chaîne à l'enfant et l'enfant le lit caractère par caractère et il génère la sortie standard:

#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); 
} 

Dans ce cas, puisque les deux processus enfants et parents sont dans le même contexte, je aurais pu utiliser une paire de tuyaux anonyme créée avec pipe(), mais cela illustre le flux, y compris la création du canal nommé.

+0

Donc, le parent devrait écrire dans la pipe après l'appel d'attente ou avant? – Alex

+0

@Alex Avant. Le 'wait()' retournera quand l'enfant se termine. Le 'write()' bloquera jusqu'à ce que l'enfant 'le lise()'. – Kusalananda

+0

J'ai créé pipe avant fork() et write() est après wait() mais reste coincé. – Alex