A voir également:
- Probleme de synchronisation
- Synchronisation calendrier outlook gmail - Guide
- Logiciel de synchronisation - Télécharger - Sauvegarde
- Synchronisation de la ligne adsl free ✓ - Forum Freebox
- Synchronisation impossible steam ✓ - Forum Jeux vidéo
- Synchronisation des dossiers avec abonnement - Forum Mail
6 réponses
Je n'ai pas pris le temps de démonter tout le programme , mais quelques remarques me viennent:
- write(dp,&mot,sizeof(mot)+1);, non il faut mettre 'strlen(mot)' car sizeof(mot)+1 donnera 11 et ce n'est pas ce que tu veux.
- for(;;) { pause(); }, 'pause()' est inutile.
- while(suite[j]!='\0') est identique à ' while(suite[j])'
- As-tu fait attention au fait que l'ouverture d'un pipe en lecture est bloquante tant qu'un autre processus ne l'a pas ouvert en écriture et lycée de versailles! En conséquence, la séquence suivante ne devrait pas fonctionner:
- re=read(dp3,ans,sizeof(ans)); printf("egal à %s\n",ans); rien ne dit que 'ans' sera terminé par un '\0'
- execv("prog2",&pidpere); heu, ce ne serait pas plutôt 'prog3',
Beaucoup d'imprécisions et je m'arrête là, ... et il n'est guère surprenant que le programme ne fait pas ce que l'on attend de lui mais seulement ... ce qu'on lui a demandé.
Je te souhaite beaucoup de persévérance.
NB: "touslemonde" s'écrit "tout le monde" ;-)
- write(dp,&mot,sizeof(mot)+1);, non il faut mettre 'strlen(mot)' car sizeof(mot)+1 donnera 11 et ce n'est pas ce que tu veux.
- for(;;) { pause(); }, 'pause()' est inutile.
- while(suite[j]!='\0') est identique à ' while(suite[j])'
- As-tu fait attention au fait que l'ouverture d'un pipe en lecture est bloquante tant qu'un autre processus ne l'a pas ouvert en écriture et lycée de versailles! En conséquence, la séquence suivante ne devrait pas fonctionner:
//ouverture du pipe pour parler à 1 dp3 = open("pipe3", O_WRONLY); if (!dp3) erreur("pb ouverture du pipe 3"); //envoi du signal pour dire d'ouvrir l'autre côté du pipe kill(pid_gp, SIGUSR1);
- re=read(dp3,ans,sizeof(ans)); printf("egal à %s\n",ans); rien ne dit que 'ans' sera terminé par un '\0'
- execv("prog2",&pidpere); heu, ce ne serait pas plutôt 'prog3',
Beaucoup d'imprécisions et je m'arrête là, ... et il n'est guère surprenant que le programme ne fait pas ce que l'on attend de lui mais seulement ... ce qu'on lui a demandé.
Je te souhaite beaucoup de persévérance.
NB: "touslemonde" s'écrit "tout le monde" ;-)
"- execv("prog2",&pidpere); heu, ce ne serait pas plutôt 'prog3',"
-> oui effectivement
"- re=read(dp3,ans,sizeof(ans)); printf("egal à %s\n",ans); rien ne dit que 'ans' sera terminé par un '\0'"
-> pourquoi ? le caractère de terminaison d'un mot n'est il pas \0 ?
effectivement "tout le monde" et pas "tous le monde".
Quand vous dites que la séquence suivant ne peux pas fonctionner :
//ouverture du pipe pour parler à 1
dp3 = open("pipe3", O_WRONLY);
if (!dp3)
erreur("pb ouverture du pipe 3");
//envoi du signal pour dire d'ouvrir l'autre côté du pipe
kill(pid_gp, SIGUSR1);
c'est parce que kill est apres open ?
il faudrait mettre le kill avant le open c'est bien ca ?
Merci d'avoir pris le temps de jeter un oeil a mon programme qui, il est vrai est un peu long a relire...
-> oui effectivement
"- re=read(dp3,ans,sizeof(ans)); printf("egal à %s\n",ans); rien ne dit que 'ans' sera terminé par un '\0'"
-> pourquoi ? le caractère de terminaison d'un mot n'est il pas \0 ?
effectivement "tout le monde" et pas "tous le monde".
Quand vous dites que la séquence suivant ne peux pas fonctionner :
//ouverture du pipe pour parler à 1
dp3 = open("pipe3", O_WRONLY);
if (!dp3)
erreur("pb ouverture du pipe 3");
//envoi du signal pour dire d'ouvrir l'autre côté du pipe
kill(pid_gp, SIGUSR1);
c'est parce que kill est apres open ?
il faudrait mettre le kill avant le open c'est bien ca ?
Merci d'avoir pris le temps de jeter un oeil a mon programme qui, il est vrai est un peu long a relire...
pourquoi ? le caractère de terminaison d'un mot n'est il pas \0 ?
Si le caractère de terminaison, par convention en C est '\0', mais encore faut-il le mettre! Et la fonction 'read(dp3,ans,sizeof(ans))' n'assure pas que 'ans' se terminera par un '\0' mais simplement, du fait du 'sizeof' qu'il n'y aura pas de débordement au-delà de 'ans'.
il faudrait mettre le kill avant le open c'est bien ca ?
Oui, car 'open' en écriture attendra que le tube nommé soit ouvert en lecture sauf s'il il y a une erreur d'ouverture. Lire ceci ou cela.
Bonne continuation.
Si le caractère de terminaison, par convention en C est '\0', mais encore faut-il le mettre! Et la fonction 'read(dp3,ans,sizeof(ans))' n'assure pas que 'ans' se terminera par un '\0' mais simplement, du fait du 'sizeof' qu'il n'y aura pas de débordement au-delà de 'ans'.
il faudrait mettre le kill avant le open c'est bien ca ?
Oui, car 'open' en écriture attendra que le tube nommé soit ouvert en lecture sauf s'il il y a une erreur d'ouverture. Lire ceci ou cela.
Bonne continuation.
Re-bonjour,
j'ai fait des petits changements, et je crois avoir identifié où ca blqoue, mais je ne sais pas pourquoi...
ca bloque apparemment au niveau du sprinf dans le 2nd programme
Prog1
Prog2
Prog3
j'ai fait des petits changements, et je crois avoir identifié où ca blqoue, mais je ne sais pas pourquoi...
ca bloque apparemment au niveau du sprinf dans le 2nd programme
Prog1
int main(void) { int pid,dp; char mot[10]="hello"; //creation du pipe unlink("pipe"); mkfifo("pipe",0666); //creation du fils pid=fork(); if (pid==0) execv("prog2",NULL); //ouverture du pipe dp=open("pipe",O_WRONLY); if(dp==0) erreur("pb ouverture du pipe 1"); printf("ouv 1er pipe\n"); //ecriture dans le pipe (envoi du 1er message) write(dp,&mot,strlen(mot)); //fermeture du pipe close(dp); signal(SIGUSR1,lecture); for(;;) { pause(); } exit(0); } void lecture(int sig) { int dp3,re; char ans[20]; dp3=open("pipe3",O_RDONLY); if(dp3==0) erreur("pb ouverture du pipe 3"); re=read(dp3,ans,sizeof(ans)); if(re==0) erreur("pb lecture du pipe 3"); printf("le resultat 3 est\n"); printf("egal à %s\n",ans); usleep(500); close(dp3); } void erreur(char *mes) { perror(mes); exit(-1); }
Prog2
int main(void) { int dp,dp2,re,pid5; char ans[20]; char suite[15]="toutlemonde"; char *pidpere; unlink("pipe2"); mkfifo("pipe2",0666); //ouverture du pipe dp=open("pipe",O_RDONLY); if(dp==0) erreur("pb ouverture du pipe 1"); printf("ouverture autre cote pipe1\n"); //lecture re=read(dp,ans,sizeof(ans)); if(re==0) erreur("pb lecture du pipe 1"); printf("le resultat est\n"); printf("egal à %s\n",ans); printf("avant fermeture dans 2\n"); usleep(500); //on attend que 1 ecrive dans le pipe close (dp); printf("apres fermeture\n"); sprintf(pidpere ,"%d", getppid()); printf("apres sprintf\n"); pid5=fork(); if (pid5==0) execv("prog3",&pidpere); //modification du message int i=0; while(ans[i]!='\0') i++; int j=0; while(suite[j]!='\0') { ans[i+j]=suite[j]; j++; } strcpy(&ans[i+j],"\0"); //envoi du signal a prog3 pour ouvrir l'autre cote du pipe kill(pid5,SIGUSR2); //ouverture du 2nd pipe dp2=open("pipe2",O_WRONLY); if(dp2==0) printf("pb ouverture du pipe 2"); //ecriture dans le pipe write(dp2,&ans,strlen(ans)); //fermeture du pipe usleep(500); close(dp2); exit(0); } void erreur(char *mes) { perror(mes); exit(-1); }
Prog3
int main(int argc, char *argv[]) { pid_gp=atoi(argv[1]); printf("le pid du gd pere est %d\n",pid_gp); unlink("pipe3"); mkfifo("pipe3",0666); signal(SIGUSR2,modif); for(;;) { pause(); } exit(0); } void modif(int sig) { int dp2,re,dp3; char ans[20]; char suite[15]="oui"; //ouverture du pipe dp2=open("pipe2",O_RDONLY); if(dp2==0) erreur("pb ouverture du pipe 2"); //lecture re=read(dp2,ans,sizeof(ans)); if(re==0) erreur("pb lecture du pipe"); printf("le resultat chez 5 est\n"); printf("egal à %s\n",ans); //fermeture usleep(500); close (dp2); //modification du message int i=0; while(ans[i]!='\0') i++; int j=0; while(suite[j]!='\0') { ans[i+j]=suite[j]; j++; } strcpy(&ans[i+j],"\0"); //envoie du signal pour dire d'ouvrir l'autre cote du pipe kill(pid_gp,SIGUSR1); //ouverture du pipe pour parler a 1 dp3=open("pipe3",O_WRONLY); if(dp3==0) erreur("pb ouverture du pipe 3"); //ecriture dans le pipe write(dp3,&ans,strlen(ans)); usleep(500); close(dp3); } void erreur(char *mes) { perror(mes); exit(-1); }
j'ai appuyé sur ajouter au lieu de prévisualiser...
donc voila la fin de mon message:
Quand j'exécute le programme, le printf("apres sprintf\n") ne s'affiche pas...donc je pense que c'est par là que ca bloque, mais pourquoi ?
Merci
donc voila la fin de mon message:
Quand j'exécute le programme, le printf("apres sprintf\n") ne s'affiche pas...donc je pense que c'est par là que ca bloque, mais pourquoi ?
Merci
Ben oui, c'est normal, rien que du classique !!!
Quant un programme (en C) plante, dans 99% des cas (au moins :-) ), il y a un problème de pointeur !
Il est donc nécessaire d'initialiser le pointeur par un:
Il faut comprendre qu'un pointeur ne s'utilise pas à la légère, sinon il faut envisager d'utiliser des langages qui ne pose pas ce genre de problème (par exemple Perl ou Python):
- déclaration,
- initialisation ou allocation,
- utilisation,
- destruction.
Ces quatre commandements sont la Bible des pointeurs en C. Il n'y a aucune aide de la part du compilateur; c'est au programmeur de gérer ses pointeurs.
Bon courage.
Quant un programme (en C) plante, dans 99% des cas (au moins :-) ), il y a un problème de pointeur !
char* pidpere; sprintf (pidpere , "%d", getppid());Il faut bien comprendre que 'pidpere' est un pointeur qui ne pointe sur rien ou plutôt sur n'importe quoi. Il va donc écrire l'entier obtenu par 'getppid()' n'importe où avec les conséquences que tu connais.
Il est donc nécessaire d'initialiser le pointeur par un:
char* pidpere = (char*)malloc(16);Avec 16, on est peinard pour la longueur de l'entier.
Il faut comprendre qu'un pointeur ne s'utilise pas à la légère, sinon il faut envisager d'utiliser des langages qui ne pose pas ce genre de problème (par exemple Perl ou Python):
- déclaration,
- initialisation ou allocation,
- utilisation,
- destruction.
Ces quatre commandements sont la Bible des pointeurs en C. Il n'y a aucune aide de la part du compilateur; c'est au programmeur de gérer ses pointeurs.
Bon courage.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Merci loupius !
Avec un malloc et un free, ca marche (enfin j'ai d'autres problemes plus loin avec les signaux, mais je vais voir ce que je peux y faire avant de demander...)
Une petite question quand meme: le pointeur il fallait l'initialiser. Est ce que ca aurait marché avec un tableau au lieu d'un pointeur, par exemple avec un char *argv[16] ?
Car un tableau, ca s'initialise ?
Avec un malloc et un free, ca marche (enfin j'ai d'autres problemes plus loin avec les signaux, mais je vais voir ce que je peux y faire avant de demander...)
Une petite question quand meme: le pointeur il fallait l'initialiser. Est ce que ca aurait marché avec un tableau au lieu d'un pointeur, par exemple avec un char *argv[16] ?
Car un tableau, ca s'initialise ?
Oh là là, pin pon pin pon pin pon !!!
Que crois-tu définir avec char *argv[16] ?
Alors, il faut savoir que [] est prioritaire sur *, donc on peut écrire (char*)(argv[16]), c'est à dire un tableau de 10 pointeurs vers des objets de type 'int'... c'est bien ce que tu voulais ?
Dans le cas qui nous intéresse, il suffit d'écrire:
Que crois-tu définir avec char *argv[16] ?
Alors, il faut savoir que [] est prioritaire sur *, donc on peut écrire (char*)(argv[16]), c'est à dire un tableau de 10 pointeurs vers des objets de type 'int'... c'est bien ce que tu voulais ?
Dans le cas qui nous intéresse, il suffit d'écrire:
char tableau[16]; sprintf (tableau, "%d", getppid());Allez encore un p'tit effort et t'auras tout compris ;-)