La lecture et l'écriture de données par l'intermédiaire d'un tuyau

J'ai créé deux processus avec fork(). L'enfant est en train de produire et de l'écriture en continu une quantité variable de données (tableau de char) à la pipe. Le processus parent lit le canal et affiche les données reçues vers stdout.

Le code est très simple:

switch (fork()) {
  case -1: 
    exit (1);
    break;
  case 0:
    close(fd[0]);
    generate_data(fd[1]);
    break;
  default:
    close(fd[1]);
    while(1) {
        n = read(fd[0], readbuffer, sizeof(readbuffer));
        readbuffer[n] = 0;
        if (n > 0)
            printf ("read: %s\n", readbuffer);            
        else
            exit(1);
    }   
   break;
}   

generate_data(int) itère sur une liste, l'écriture de chaque élément (string) pour le descripteur de fichier donné en argument (l'écriture, à la fin de la pipe dans ce cas):

void generate_data(int fd) 
{
   node_t node* = list;
   while (node != NULL) {
     write(fd, node->data, strlen(node->data)+1);
     node = node->next();
   }

}

Le problème ici est que la sortie est toujours imprévisible: le processus de l'enfant écrit des données dans la conduite, l'autre est du traitement de la dernière read, donc quand il invite à relire le reste des données n'est plus là.

Selon man 2 pipe, cela ne devrait pas se produire:

Les données écrites à l'écriture, à la fin de la pipe est tempérée par l'
noyau jusqu'à ce qu'il est lu à partir de la fin de lecture de la pipe.

De prendre une liste de 10 éléments, certains exemples de sortie:

Exemple 1:

read: element_4
read: element_8
read: element_9

Exemple 2:

read: element_7
read: element_8
read: element_9
read: element_10

Exemple 3:

read: element_2
read: element_8

Quelqu'un a une idée de ce qui se passe ici?

  • Pas sans le code indiquant l'écriture, et peut-être quelques exemple de sortie.
  • Quel est le problème exactement? Mineur pinaille: read() ne lit pas null cordes. votre de format %s s'attend à une chaîne terminée par le caractère nul. Peut-être que vous devriez ajouter "readbuffer[n] = 0;" après la lecture, étant donné le manque d'espace.
  • Merci pour les commentaires. J'ai juste modifié la question avec plus d'information.
  • Lire ma réponse soigneusement -- il explique exactement ce qu'est le problème, et votre code ci-dessus le confirme. generate_data est le fait d'envoyer plusieurs 0 chaînes terminées au cours de la pipe; printf est juste l'impression de la première. Remplacer les zéros par des retours à la ligne dans generate_data, ou de les analyser dans votre lecture de code. Mais l'essentiel, c'est que printf est ignorant la plupart de ce que vous donnez, car il arrête l'impression lors de la première de 0 octet.
InformationsquelleAutor alnacle | 2011-09-07