De la Pipe, de la Fourche, et Exec - Communication dans les Deux sens Entre le Parent et l'Enfant

Une affectation dans mes Systèmes d'Exploitation de la classe me demande de construire un processus binaire de l'arbre de manière récursive par l'appel exec sur le même programme. L'objectif est de diviser certains arbitraire des tâches dans des processus séparés. Le parent doit communiquer avec les enfants, et les enfants avec le parent uniquement via sans nom tuyaux. L'idée est que le parent envoie à chaque enfant la moitié de l'ouvrage et cela continue récursivement jusqu'à ce qu'un cas de base est respectée lorsque la longueur de la chaîne est passée à chaque enfant est <= 2. Ensuite, l'enfant traite ces données et envoie les résultats à la maison mère à travers des tuyaux.

Pour obtenir une meilleure compréhension de la façon dont les deux sens de la communication travaille avec des tuyaux en c j'ai créé le programme simple avant de passer à l'attribution. Le parent ne lit jamais les données du processus enfant. J'attends la sortie...

parent ou d'un message reçu: test

Au lieu de cela, quand j'ai l'impression que je reçois...

parent ou d'un message reçu:

Il semble que le buff est vide et pas de la lecture de l'enfant. Quelqu'un peut-il expliquer ce que je fais mal et/ou de la manière standard de

  1. écrit à exec avais de l'enfant du parent
  2. lecture du parent dans exec avais enfant
  3. rédaction de retour à parent de exec avais enfant
  4. lecture de exec avais de l'enfant dans le parent

Je suis obligé d'utiliser exec(), pipe(), fork(). Merci.

/**
* *********************************
* two_way_pipes.c
* *********************************
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <sys/time.h> 
#include <sys/types.h> 
#include <unistd.h>
#define PARENT_READ read_pipe[0]
#define PARENT_WRITE write_pipe[1]
#define CHILD_WRITE read_pipe[1]
#define CHILD_READ  write_pipe[0]
#define DEBUGGING 1
int main(int argc, char **argv) {
char buff[5];
//in the child process that was exec'd on the orginal call to two_way_pipes
if(argc == 2) {
read(STDIN_FILENO, buff, 4); //this should read "test" from stdin
buff[4] = '\0';
fprintf(stdout, "%s\n", buff); //this should right "test" to stdout and be read by the parent process
//int the root process, the original call to two_way_pipes with no args
} else {
int pid;
int read_pipe[2];
int write_pipe[2];
pipe(read_pipe);
pipe(write_pipe);
pid = fork();
//parent process
if(pid > 0) {
close(CHILD_READ);
close(CHILD_WRITE);
write(PARENT_WRITE, "test", 4); //attempting to write this to the child
struct timeval tv;
fd_set readfds;
tv.tv_sec = 10;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(PARENT_READ, &readfds);
select(PARENT_READ + 1, &readfds, NULL, NULL, &tv);
if(FD_ISSET(PARENT_READ, &readfds)) {
read(PARENT_READ, buff, 4); //should read "test" which was written by the child to stdout
buff[4] = '\0';
close(PARENT_READ);
close(PARENT_WRITE);
fprintf(stderr, "in parent | message received: %s\n", buff);  //"test" is not in buff
}
//child process
} else if(pid == 0) {
close(PARENT_READ);
close(PARENT_WRITE);
dup2(CHILD_READ, STDIN_FILENO);
dup2(CHILD_WRITE, STDOUT_FILENO);
close(CHILD_READ);
close(CHILD_WRITE);
char *argv2[] = {"some random arg to make sure that argc == 2 in the child", NULL};
execvp("two_way_pipes", argv2);
_exit(0);
//error forking child process
} else {
fprintf(stderr, "error forking the child\n");
}
}
}

Mise à jour

Basé sur Jonathon de réponse, j'ai modifié le arg2 tableau transmis dans execvp...

char *argv2[] = {"two_way_pipes", "1", NULL};
execvp("two_way_pipes", argv2);

Cela n'a pas de résoudre le problème. La mère n'était toujours pas en mesure de lire "test" de retour de la part du client. Toutefois, en réponse à Jonathon la réponse de William le commentaire que j'ai commencé à bidouiller mon exec appel et pour une raison de le changer pour la ligne ci-dessous montrent travaillé.

execl("two_way_pipes", "two_way_pipes", "1", NULL);

Je serai heureux d'accepter toutes les réponses pour expliquer pourquoi la execvp appel ne fonctionne pas mais le execl appel n'.

Est votre exevp succès? Essayez de remplacer le _exit(0) avec perror( "execvp" )
Merci William. J'ai remplacé le _exit(0) avec perror("execvp"). Ce message d'erreur jamais imprimé, mais j'ai commencé à bidouiller mon exec appel et pour une raison quelconque modification de l'appel à execl("two_way_pipes", "two_way_pipes", "1", NULL); correction du problème.
Ce code, par conséquent, manque de tester le résultat de l'appel système. Pas fait faire de test et de débogage dur et le programme faible. Veuillez voir ma réponse.

OriginalL'auteur Anthony Jack | 2013-10-04