2013-09-27 3 views
0

У меня возникли трудности с внедрением межпроцессного взаимодействия на C. Я упростил свою проблему до следующего блока кода, в котором я создаю каналы, разворачиваю процесс и перенаправляю IO для ребенка:Общение с дочерними процессами с использованием каналов, перенаправления и фидов

int main(void) { 
    int parentToChild[2]; 
    int childToParent[2]; 
    pid_t pid = 1; 
    char buffer[80]; 
    FILE *writeStream; 
    FILE *readStream; 

    pipe(parentToChild); 
    pipe(childToParent); 

    pid = fork(); 

    if(pid == 0) { // I'm the child. I read from stdin, and write to stdout. 
     close(parentToChild[1]); 
     close(childToParent[0]); 
     dup2(parentToChild[0], 0); 
     dup2(childToParent[1], 1); 
     close(parentToChild[0]); 
     close(childToParent[1]); 
     fgets(buffer, 80, stdin); // wait for the parent to send something 
     fprintf(stderr, "I got %s\n", buffer); // tell the world I got it 
     fprintf(stdout, "Child message\n"); // send message back to the parent 
    } 

    if(pid != 0) { // I'm a parent 
      close(parentToChild[0]); 
      close(childToParent[1]); 
      /* writeStream connected to stdin of child */ 
      writeStream = fdopen(parentToChild[1], "w"); 
      /* readStream connected to stdout of child. */ 
      readStream = fdopen(childToParent[0], "r"); 
      fprintf(writeStream, "Hello, World!\n"); 
      fgets(buffer, 80, readStream); // comment this out and the child will be able to read the "Hello World". Why is this? 
      fprintf(stderr, "Parent just got %s", buffer); 
    } 



    return 0; 

}           

Если я выполняю это, родитель просто, кажется, ждет ребенка навсегда. Что-то явно не так, как настроены мои потоки? Если у меня есть это, так что ребенок только читает, а родитель пишет только (или наоборот), он работает нормально, но я не могу управлять тем, что оба процесса обрабатывают чтение и запись. Порядок кажется прекрасным, когда ребенок ожидает сначала stdin, а родительский пишут сначала.

Спасибо.

ответ

1

Когда я fflush (writeStream) после родительского fprintf(writeStream, "Hello, World!\n") все работает нормально. Я считаю, что проблема с буферизацией трубы.

Попробуйте взглянуть на man 3 setvbuf

setvbuf() функция может быть использована на любом открытом потоке, чтобы изменить свой буфер. Аргумент режим должен быть один из следующих трех макросов:

  _IONBF unbuffered 
     _IOLBF line buffered 
     _IOFBF fully buffered 

так что я думаю, что установка вашего WriteStream к _IONBF (небуферизованном) решит эту проблему.

0

dup2 От человека страницы:

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

Таким образом, закрытие одной из труб закрывает один из стандартных файловых дескрипторов. Не делай этого.

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