2010-05-29 7 views
1

Je veux créer un programme simple, cette branche, et l'enfant écrit dans le canal nommé et le parent lit et affiche à partir du canal nommé. Le problème est qu'il entre dans le parent, fait le premier printf et puis il devient bizarre, il ne fait rien d'autre, ne parvient pas à la deuxième printf, juste des façons d'entrer dans la console.C Tuyau nommé (fifo). Le processus parent est bloqué

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
void main() 
{ 
char t[100]; 
mkfifo("myfifo",777); 
pid_t pid; 
pid = fork(); 
if (pid==0) 
{ 
    //execl("fifo2","fifo2",(char*)0); 
    char r[100]; 
    printf("scrie2->"); 
    scanf("%s",r); 

    int fp; 
    fp = open("myfifo",O_WRONLY); 
    write(fp,r,99); 
    close(fp); 
    printf("exit kid \n"); 
    exit(0); 
} else 
{ 
    wait(0); 
    printf("entered parent \n"); // <- this it prints 
    // whats below this line apparently its not being executed 
    int fz; printf("1"); 
    fz = open("myfifo",O_RDONLY); printf("2"); 
    printf("fd: %d",fz); 
    char p[100]; 
    int size; 
    printf("------"); 
    //struct stat *info; 
    //stat("myfifo",info); printf("%d",(*info).st_size); 
    read(fz,p,99); 
    close(fz); 
    printf("%s",p); 

    printf("exit"); exit(0); 
} 
} 

Répondre

3

tout d'abord, essayez fprintf stderr au lieu de printf (à stdout)

Le stderr est unbuffered.

Ensuite, vous pouvez dire ce qui est réellement imprimé et ce qui ne l'est pas.

ou au moins d'ajouter fflush avant d'attendre quoi que ce soit.

5

Vous devriez vraiment vérifier la valeur de retour sur les appels de fonction pour les erreurs, en particulier mkfifo() et open(). Votre appel à wait() va causer des problèmes à son emplacement actuel. Ouverture d'un FIFO pour la lecture normalement bloque jusqu'à un autre processus ouvre la même FIFO pour l'écriture, et vice versa . Le parent attend que l'enfant se termine et l'enfant attend un processus de lecture, c'est-à-dire le parent, pour se connecter à la FIFO.

1 - voir la note open() ci-dessous pour l'utilisation O_NONBLOCK avec un FIFO

Déplacement de l'appel à juste wait() avant que le processus parent quitte ainsi que la modification du mode dans l'appel à mkfifo()-0666 semble résoudre certains de vos problèmes immédiats.

Il est également recommandé d'enlever le FIFO lorsque vous en avez fini avec lui.

unlink("myfifo"); 

De l'open() function documentation in IEEE Std 1003.1-2004:

Lors de l'ouverture d'un FIFO avec O_RDONLY ou O_WRONLY set:

  • Si O_NONBLOCK est défini, un open() pour la lecture seule doit retourner sans délai. Un open() pour écriture seule doit renvoyer une erreur si aucun fichier n'a actuellement ouvert le fichier en lecture.

  • Si O_NONBLOCK est effacé, open() en lecture seule doit bloquer le thread appelant jusqu'à ce qu'un thread ouvre le fichier en écriture. Un open() pour écriture seule doit bloquer le thread appelant jusqu'à ce qu'un thread ouvre le fichier à lire.


L'exemple suivant est une combinaison des code in your original question et FIFO page of Beej's Guide to Unix IPC:

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

#define FIFO_NAME "myfifo" 

int main(void) 
{ 
    char buf[256]; 
    int num, fd; 
    pid_t pid; 

    if (mkfifo(FIFO_NAME, 0666) < 0) 
     perror("mkfifo"); 

    pid = fork(); 
    if (pid == 0) 
    { 
     printf("child - waiting for readers...\n"); 
     if ((fd = open(FIFO_NAME, O_WRONLY)) < 0) 
      perror("child - open"); 

     printf("child - got a reader -- type some stuff\n"); 
     while (fgets(buf, sizeof(buf), stdin), !feof(stdin)) 
     { 
      if ((num = write(fd, buf, strlen(buf))) < 0) 
       perror("child - write"); 
      else 
       printf("child - wrote %d bytes\n", num); 
     } 

     close(fd); 
     exit(0); 
    } 
    else 
    { 
     printf("parent - waiting for writers...\n"); 
     if ((fd = open(FIFO_NAME, O_RDONLY)) < 0) 
      perror("parent - open"); 

     printf("parent - got a writer\n"); 
     do 
     { 
      if ((num = read(fd, buf, sizeof(buf))) < 0) 
       perror("parent - read"); 
      else 
      { 
       buf[num] = '\0'; 
       printf("parent - read %d bytes: \"%s\"\n", num, buf); 
      } 
     } while (num > 0); 

     close(fd); 
     wait(0); 
    } 

    unlink(FIFO_NAME); 
    return 0; 
}

Cet exemple a été testé sous Linux. Appuyez sur Ctrl - D pour terminer le programme.

+0

j'ouvre le FIFO mais je le ferme dans le même processus. donc ça ne devrait pas bloquer. et j'ai BESOIN que mon parent attende après son enfant, parce que l'enfant reçoit des entrées, et je ne peux pas ne pas attendre sur la première ligne du parent parce que cela signifierait commencer à lire du fifo, quand je n'ai même pas fini pour écrire dessus – Blitzkr1eg

+0

maintenant j'ai: char c [2]; c [1] = 0; c [0] = 0; c [0] = strlen (r); // c [0] est disons 4 écrivent (fp, c, 1); // fp est le FIFO puis dans un autre processus: // pipe ouverte, je vérifie les erreurs, mais il n'y a pas d'erreur, donc ça ouvre bien char c [2]; c [1] = 0; c [0] = 0; lu (fz, c, 1); // fz est le canal // et maintenant c [0] vaut 0 au lieu de ce qu'il devrait être, 4 – Blitzkr1eg

+0

Il peut être difficile de suivre les changements de code décrits dans les commentaires. Vous feriez mieux de modifier votre question pour montrer ce que vous avez essayé. J'ai ajouté un exemple à ma réponse qui devrait vous aider. – jschmier

Questions connexes