Je voudrais écrire un petit programme pour m'entrainer avec la communication entre 2 processus pere et fils en language C.
J'ai codé un programme pere (arnaud.c) qui demande à l'utilisateur de taper une chaine de caracteres.


Il trie cette chaine, et envoie les lettres à une de ses fils (bob.c) et les chiffre à l'autre (charly.c).
Chaque fils lit ce qui lui est envoyé, et le renvoie au père à la fin du processus.
La communication pere fils se fait avec un pipe
(je reconnais que mon programme ne sert à rien, mais c'est pour m'entrainer)
Mon programme compile, mais ne marche pas: il se bloque et attend (donc je pense un probleme de synchronisation pere-fils). De plus chaque fils n'a l'air de lire que le 1er caractère( a l'air car comme ca se bloque, je ne suis pas sur...)
Voilà le code de mes 3 programmes (je reconnais qu'ils sont un peu longs...). Si vous pouviez jeter un oeuil et me dire ce qui bloque dans mon programme (et surtout pourquoi ca bloque), ce serait vraiment sympa.


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 
-----------------------------------arnaud.c---------------------------------------------
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<signal.h>
void erreur(char *mes);
char tab[10];
int main(void)
{
int pidb,pidc,p1;
int bip=0;
char car[10];
// creation du pipe
unlink("pipe");
mkfifo("pipe",0666);
// creation des 2 fils
pidb=fork();
if (pidb==0) execv("bob",NULL);
pidc=fork();
if (pidc==0) execv("charly",NULL);
//ouverture d'un pipe en ecriture
p1=open("pipe",O_WRONLY);
if (p1==-1) erreur("pb d'ouverture en ecriture");
printf("\ntaper une sequences de caracteres\n");
scanf("%s",&car);
// lecture des caracteres
int i=0;
while(car[i]!='\0') // pas de &car[i]
{
// tri+envoi d'un signal au fils approprié
usleep(500);
if (car[i]>='A' && car[i]<='z')
kill(pidb,SIGUSR1);
else if (car[i]>='1' && car[i]<='9')
kill(pidc,SIGUSR1);
else
{
printf("caractere non valide\n");
bip=1; // on n'ecrit rien dans le pipe
}
// écriture dans le pipe
if (bip==0) write(p1,&car[i],sizeof(car));
i++;
}
// on envoie le message de fin de l'ecriture qui est "!"
char fin;
fin='!';
write(p1,&fin,sizeof(car));
//on referme le pipe en écriture
usleep(500);
close(p1);
// on ouvre le pipe en lecture
p1=open("pipe",O_RDONLY);
if (p1==-1) erreur("pb d'ouverture en lecture");
//on lit
int j;
for(j=0;j=10;j++)
{
read(p1,&tab[j],sizeof(tab));
printf("%s",&tab[j]);
}
//on referme le pipe en lecture
usleep(500);
close(p1);
// on tue les processus
kill(pidb,SIGKILL);
kill(pidc,SIGKILL);
return(0);
}
void erreur(char *mes)
{
printf("%s\n",mes);
exit(-1);
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 
/---------------------------------------------------------bob.c------------------------------------
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<signal.h>
void erreur(char *mes);
void lect(int sig);
void envoyer();
// s'occupe des lettres
int p1;
int i=0;
char tab[10][10];
int main(void)
{
//ouverture d'un pipe en lecture
p1=open("pipe",O_RDONLY);
if (p1==-1) erreur("pb d'ouverture en lecture\n");
// on se prepare au signal
signal(SIGUSR1,lect);
// on verifie si le signal de fin a ete envoyé
char fin;
fin='!';
if (strcmp(&tab[10][i],&fin)==0)
envoyer();
// on attend le signal
for(;;)
{
pause();
}
exit(0);
}
void lect(int sig)
{
char lett;
// lecture du pipe
read(p1,&lett,sizeof(lett));
//on stocke la variable ds un tableau
tab[10][i]=lett;
i++;
// on affiche le resultat
printf("la lettre lue est %c\n", lett);
//on referme le pipe
close(p1);
}
void envoyer()
{
//on ouvre le pipe en éccriture cette fois ci
p1=open("pipe",O_WRONLY);
write(p1,tab,sizeof(tab));
close(p1);
}
void erreur(char *mes)
{
printf("%s\n",mes);
exit(-1);
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 
//-----------------------------------------------------charly.c---------------------------------------------
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<signal.h>
void erreur(char *mes);
void lect(int sig);
void envoyer();
// s'occupe des chiffres
int p1;
int i=0;
char tab[10][10];
int main(void)
{
//ouverture d'un pipe en lecture
p1=open("pipe",O_RDONLY);
if (p1==-1) erreur("pb d'ouverture en lecture\n");
// on se prepare au signal
signal(SIGUSR1,lect);
// on verifie si le signal de fin a ete envoyé
char fin;
fin='!';
if (strcmp(&tab[10][i],&fin)==0)
envoyer();
// on attend le signal
for(;;)
{
pause();
}
exit(0);
}
void lect(int sig)
{
char chiff;
// lecture du pipe
read(p1,&chiff,sizeof(chiff));
//on stocke la variable ds un tableau
tab[10][i]=chiff;
i++;
// on affiche le resultat
//printf("la lettre lue est %c\n", lett);
//on referme le pipe
close(p1);
}
void envoyer()
{
//on ouvre le pipe en éccriture cette fois ci
p1=open("pipe",O_WRONLY);
write(p1,tab,sizeof(tab));
close(p1);
}
void erreur(char *mes)
{
printf("%s\n",mes);
exit(-1);
}