I'm currently working on a project involving 4 processes that communicate through named pipes. However i don't ALWAYS get the results i expect. Writers are just sending an int equal to the process pid.
Here is a short executable code i made to illustrate my problem :
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
int main(void){
int i, j, k, pid;
int childs = 4;
int size = 16;
char nomTube[size];
for(j = 0; j < childs; j++)
{
sprintf(nomTube, "assistant%d.fifo", j);
if(mkfifo(nomTube, 0777) != 0)
{
fprintf(stderr, "Impossible de créer le tube nommé.\n");
//exit(EXIT_FAILURE);
}
}
for(i = 0; i < childs; i++)
{
if(fork() == 0)
{
pid = i;
if(pid % 2 == 0)
{Writing(pid); printf("Child(%d) writing done;\n", pid);}
else
{Reading(pid); printf("Child(%d) reading done;\n", pid);}
break;
}
}
for(k = 0; k < childs; k++)
{
wait(NULL);
}
return 0;}
Now the Writing function :
void Writing(int pid){
int entreeTube;
int var = pid;
int i;
if(pid == 0)
{
for(i = 0; i < 2; i++)
{
printf("Child(%d) i'm writing to Child(%d) var = %d;\n", pid, 1, var);
if((entreeTube = open("assistant1.fifo", O_WRONLY)) == -1)
{
fprintf(stderr, "Impossible d'ouvrir l'entrée du tube nommé.\n");
//exit(EXIT_FAILURE);
}
write(entreeTube, &var, sizeof(int));
}
}
else if(pid == 2)
{
for(i = 0; i < 2; i++)
{
printf("Child(%d) i'm writing to Child(%d) var = %d;\n", pid, 3, var);
if((entreeTube = open("assistant3.fifo", O_WRONLY)) == -1)
{
fprintf(stderr, "Impossible d'ouvrir l'entrée du tube nommé.\n");
//exit(EXIT_FAILURE);
}
write(entreeTube, &var, sizeof(int));
}
}}
Now the Reading function :
void Reading(int pid){
int sortieTube;
int var = -1;
int i;
if(pid == 1)
{
for(i = 0; i < 2; i++)
{
if((sortieTube = open ("assistant1.fifo", O_RDONLY)) == -1)
{
fprintf(stderr, "Impossible d'ouvrir la sortie du tube nommé.\n");
//exit(EXIT_FAILURE);
}
read(sortieTube, &var, sizeof(int));
printf("Child(%d) var = %d\n", pid, var);
}
}
else if(pid == 3)
{
for(i = 0; i < 2; i++)
{
if((sortieTube = open ("assistant3.fifo", O_RDONLY)) == -1)
{
fprintf(stderr, "Impossible d'ouvrir la sortie du tube nommé.\n");
//exit(EXIT_FAILURE);
}
read(sortieTube, &var, sizeof(int));
printf("Child(%d) var = %d\n", pid, var);
}
}}
So basically :
- Child(0) writes to "assistant1.fifo" 2 times | writes 0
- Child(2) writes to "assistant3.fifo" 2 times | writes 2
- Child(1) reads "assistant1.fifo" 2 times | reads 0
- Child(3) reads "assistant3.fifo" 2 times | reads 2
Sometimes it works but some other times it just blocks. You might have to execute a few times to see it block though.
Is this a sync problem? Even though writing/reading are blocking?
I don't see where the problem is... so i think i'm missing something related to the pipe mechanics. Do you see what's wrong ?
My apologies for the code editing and indentation, and also for my english, i hope you understand me good enough.
I believe i found the awnser. I resolved the problem by opening only once the mkfifo both in writing and reading. Then comes the loop wich writes or reads.
Same thing for the reading process. Even though it is working just fine, if someone knows the mechanics behind all this and can explain them i would be grateful. Thank you very much :)