2010-05-29 2 views
1

Я хочу сделать простую программу, которая вилка, и ребенок записывает в именованный канал, а родительский читает и отображает из именованного канала. Проблема в том, что он входит в родительский, делает первый printf, а затем становится странным, он ничего не делает, не попадает во второй printf, это просто способы ввода в консоль.C Именованная труба (fifo). Родительский процесс застрял

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
void main() 
{ 
char t[100]; 
mkfifo("myfifo",777); 
pid_t pid; 
pid = fork(); 
if (pid==0) 
{ 
    //execl("fifo2","fifo2",(char*)0); 
    char r[100]; 
    printf("scrie2->"); 
    scanf("%s",r); 

    int fp; 
    fp = open("myfifo",O_WRONLY); 
    write(fp,r,99); 
    close(fp); 
    printf("exit kid \n"); 
    exit(0); 
} else 
{ 
    wait(0); 
    printf("entered parent \n"); // <- this it prints 
    // whats below this line apparently its not being executed 
    int fz; printf("1"); 
    fz = open("myfifo",O_RDONLY); printf("2"); 
    printf("fd: %d",fz); 
    char p[100]; 
    int size; 
    printf("------"); 
    //struct stat *info; 
    //stat("myfifo",info); printf("%d",(*info).st_size); 
    read(fz,p,99); 
    close(fz); 
    printf("%s",p); 

    printf("exit"); exit(0); 
} 
} 

ответ

3

Прежде всего, попробуйте fprintf в стандартный вывод вместо Е (стандартный вывод)

стандартный поток ошибок небуферизован.

Тогда вы можете сказать, что на самом деле печатается, а что нет.

или хотя бы добавить fflush перед тем, как ждать чего-нибудь.

5

Вы действительно должны проверять возвращаемое значение на вызовы функций для ошибок, особенно mkfifo() и open().

Ваш вызов wait() вызовет проблемы в его текущем местоположении. Открытие FIFO для чтения обычно блокирует, пока какой-либо другой процесс не откроет тот же FIFO для записи, и наоборот . Родитель ожидает, когда ребенок закончит работу, и ребенок ждет процесса чтения, то есть родителя, для подключения к FIFO.

1 - примечание на open() ниже для использования O_NONBLOCK с FIFO

Перемещением wait() вызова непосредственно перед родительским процессом выходит вместе с изменением режима в вызове mkfifo() к 0666, кажется, решить некоторые ваших непосредственных проблем.

Также неплохо удалить FIFO, когда вы закончите с ним.

unlink("myfifo"); 

От open() function documentation in IEEE Std 1003.1-2004:

При открытии FIFO с O_RDONLY или O_WRONLY установить:

  • Если O_NONBLOCK установлен, открытое() для чтения только должны незамедлительно вернуться. Функция open() только для записи должна возвращать ошибку, если в текущем режиме файл не открыт для чтения.

  • Если O_NONBLOCK понятен, функция open() только для чтения блокирует вызывающий поток, пока поток не откроет файл для записи. Функция open() только для записи блокирует вызывающий поток, пока поток не откроет файл для чтения.


Следующий пример представляет собой комбинацию из code in your original question и FIFO page of Beej's Guide to Unix IPC:

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/wait.h> 
#include <unistd.h> 

#define FIFO_NAME "myfifo" 

int main(void) 
{ 
    char buf[256]; 
    int num, fd; 
    pid_t pid; 

    if (mkfifo(FIFO_NAME, 0666) < 0) 
     perror("mkfifo"); 

    pid = fork(); 
    if (pid == 0) 
    { 
     printf("child - waiting for readers...\n"); 
     if ((fd = open(FIFO_NAME, O_WRONLY)) < 0) 
      perror("child - open"); 

     printf("child - got a reader -- type some stuff\n"); 
     while (fgets(buf, sizeof(buf), stdin), !feof(stdin)) 
     { 
      if ((num = write(fd, buf, strlen(buf))) < 0) 
       perror("child - write"); 
      else 
       printf("child - wrote %d bytes\n", num); 
     } 

     close(fd); 
     exit(0); 
    } 
    else 
    { 
     printf("parent - waiting for writers...\n"); 
     if ((fd = open(FIFO_NAME, O_RDONLY)) < 0) 
      perror("parent - open"); 

     printf("parent - got a writer\n"); 
     do 
     { 
      if ((num = read(fd, buf, sizeof(buf))) < 0) 
       perror("parent - read"); 
      else 
      { 
       buf[num] = '\0'; 
       printf("parent - read %d bytes: \"%s\"\n", num, buf); 
      } 
     } while (num > 0); 

     close(fd); 
     wait(0); 
    } 

    unlink(FIFO_NAME); 
    return 0; 
}

Этот пример был протестирован в Linux. Нажмите Ctrl - D, чтобы завершить программу.

+0

Я открываю FIFO, но я закрываю его в том же процессе. поэтому он не должен блокироваться. и я НЕОБХОДИМО, что мой родительский процесс ждет после своего дочернего элемента, потому что ребенок получает вход, и я не могу не ждать в первой строке родителя, потому что это означало бы начать читать из fifo, когда я даже не закончил написать на нем – Blitzkr1eg

+0

сейчас у меня: char c [2]; c [1] = 0; с [0] = 0; c [0] = strlen (r); // c [0] позволяет сказать 4 write (fp, c, 1); // fp - это FIFO , а затем в другом процессе: // открываем трубку, проверяем наличие ошибок, но ошибок нет, поэтому открываем штраф char c [2]; с [1] = 0; с [0] = 0; читать (fz, c, 1); // fz - это труба // и теперь c [0] - это 0, а не то, что должно быть, 4 – Blitzkr1eg

+0

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

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