Regardez le code suivant:
#include<unistd.h> #include<stdlib.h> #include<stdio.h> #include<string.h> #include<sys/types.h> main() { int pipdes[2]; char buff[50]; const char parent[]="Parent Writes. Child Reads\n"; const char child[]="Child Writes. Parent Reads\n"; if(pipe(pipdes)==0) { pid_t pid=fork(); if(pid<0) printf("Error\n"); if(pid==0){ read(pipdes[0],buff,50); printf("Parent: %s",buff); write(pipdes[1], child, strlen(child)); exit(0); } else if(pid>0) { write(pipdes[1], parent, strlen(parent)); wait(pid); read(pipdes[0], buff, 50); printf("Child: %s", buff); } } else printf("Error in pipe\n"); }
3 Réponses :
sur certains systèmes, les tuyaux peuvent être bidirectionnels. Mais ils ne doivent pas être, et toute hypothèse qu'elles seront non portatives. En particulier, ils ne sont pas sous Linux.
tel qu'il est, votre code a un problème - les deux processus tentent de lire et d'écrire sur le même tuyau. L'utilisation prévue pour les pipes est que l'enfant écrit et le parent lit, ou vice versa. La voie actuelle que vous faites les choses fonctionne pour vous en ce moment, car vous lisez et écrivez une fois et Si vous souhaitez que des données circulent dans les deux sens, vous pouvez utiliser deux paires de tuyaux. Appelons-les Alternativement, vous pouvez utiliser une paire de prises UNIX créées avec attendez code> sur l'enfant. Mais quand vous boucle en essayant de faire des choses comme vous faites, vous ne pouvez pas
attendre code> - et sans la synchronisation, l'enfant sera souvent (mais pas toujours!) Finir par la lecture de ce qu'elle avait voulu Pour envoyer au parent, et vice versa. p>
parent_pipe code> et
enfant_pipe code>. Le parent lirait depuis
parent_pipe [0] code> et écrire sur
enfant_pipe [1] code>, et l'enfant lirait depuis
enfant_pipe [0] code> et écrire à
parent_pipe [1] code>. p>
socketpair (AF_LOCAL, SOCK_STREAM, 0 , Sockdes) Code> (où
sockdes code> est ce que nous avons renommé
pipdes code> à, car il s'agit des sockets maintenant et non des tuyaux). L'enfant lirait et écrit à
sockdes [0] code> et le parent lirait et écrivez à
SOCKDES [1] code>. Ou vice versa. P> p>
Eh bien, c'est exactement ce que je suis incapable de comprendre, à l'exception de la partie PID <0 (que j'ai copiée à tort), le code fonctionne bien et le parent et l'enfant lisent et écrivent dans le bon ordre.
C'est parce que (1) vous êtes attendre code> sur l'enfant. Normalement, vous venez de lire l'entrée; Avec le
attendre code>, vous écrivez, en attente de la lecture et de l'écriture de l'enfant, puis de lire. Cela fonctionne pour l'instant, mais (2) Vous ne faites qu'une itération lecture / écriture (c'est pourquoi
attendre (PID) code> fonctionne). Dans une boucle,
attendre code> ne fonctionnera pas - il ne reviendrait que lorsque l'enfant meurt. Si vous lisez et écrivez ... Dites ... 50 fois, les chances sont bonnes qu'avec une paire de tuyaux, l'enfant lira ce qu'il vient d'envoyer au parent, et inversement. HOLD ON, LEMME EDIT.
Donc, ce que vous dites, c'est que si son seul message à envoyer et à recevoir, un tuyau peut alors fonctionner bidirectionnelle. Ce qui signifie que les tuyaux ne sont pas unidirectionaux en règle générale, son juste gênant d'utiliser ensuite bidirectionnelle dans la plupart des cas.
Non, le fait que deux processus puissent partager le même tuyau ne leur rend pas bidirectionnel. S'ils étaient bidirectionnels, l'enfant pouvait lire du tuyau [0] et écrire sur la pipe [1], et le parent pourrait écrire i> à pipe [0] et lire i> de la pipe [1]. Ce que vous avez actuellement est deux processus partageant un tuyau unidirectionnel de manière à travailler semi-accidentellement.
D'ACCORD. Donc, c'est le même tuyau qui fonctionne uni-directionnel et mon code peut échanger l'expéditeur et le récepteur, et cela fonctionne dans le cas aussi simple que cela.
Non, ils ne sont pas. Il y a eu des systèmes avec des tuyaux bidirectionnels (Soleil, IIRC). Si vous avez vraiment besoin d'un tuyau bidirectionnel, vous pouvez utiliser SocketPair (). P>
Dans POSIX.1-2001, les tuyaux sont unidirectionnels. De la page man: p>
tuyau () crée une paire de descripteurs de fichier, pointant vers une pipe inode, et les place dans la matrice pointée par des griefs. Filedes [0] est pour Lecture, Filedes [1] est pour écrire. P> blockQuote>
D'ailleurs, votre utilisation de
Fork code> est incorrecte:
Fork code> Retours
pid> 0 code> pour le parent et
pid == == 0 code> pour l'enfant.
pid <0 code> signifie qu'il y avait une erreur. p>
Cela ne devrait-il pas être
pid == 0 code>, au lieu de
pid <0 code>? Je suis sûr que
fourchette () code> renvoie 0 au parent et ne renvoie que négatif dans une erreur.
Ouais, désolé pour le ça. Je n'ai pas copié le code correctement.