2016-12-22 1 views
0

В настоящее время я работаю над проектом, включающим 4 процесса, которые обмениваются данными по именованным каналам. Однако я НЕ ВСЕГДА получаю ожидаемые результаты. Писатели просто отправляют int, равный процессу pid.Обновленные именованные трубы в C | Не всегда может получить то, что ожидаю

Вот короткий исполняемый код, который я сделал, чтобы проиллюстрировать мою проблему:

#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;} 

Теперь функция Запись:

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)); 
} 
}} 

Теперь функция чтения:

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); 
} 
}} 

Так в основном :

  • Ребенок (0) пишет в «assistant1.fifo» 2 раза | пишет 0
  • Ребенок (2) пишет в «assistant3.fifo» 2 раза | записи 2
  • Ребенок (1) читает «assistant1.fifo» 2 раза | читает 0
  • Ребенок (3) читает «assistant3.fifo» 2 раза | читать 2

Иногда это работает, но в некоторые другие времена он просто блокируется. Возможно, вам придется выполнить несколько раз, чтобы увидеть его.

Это проблема синхронизации? Хотя запись/чтение блокируют?

Я не вижу, где проблема ... так что я думаю, что мне не хватает чего-то, связанного с механикой трубы. Вы видите, что случилось?

Приношу извинения за редактирование кода и отступы, а также за мой английский, надеюсь, вы меня хорошо понимаете.

ответ

0

Я считаю, что нашел тент. Я решил проблему, открыв только один раз mkfifo как в письменной форме, так и при чтении. Затем идет цикл, который пишет или читает.

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); 
    } 
    for(i = 0; i < 2; i++) 
    { 
     write(entreeTube, &var, sizeof(int)); 
    } 

То же самое для процесса чтения. Несмотря на то, что он работает отлично, если кто-то знает механику за всем этим и может объяснить их, я был бы благодарен. Большое спасибо :)

Смежные вопросы