синхронизация процесса с 2 трубами - PullRequest
0 голосов
/ 05 декабря 2018

Я делаю задание.Мне нужно написать программу на C с одним ребенком, а затем отцу и ребенку нужно вывести в stdout по одной строке для каждого.По сути, я хочу что-то вроде этого:

I'm the father
I'm the child
I'm the father
I'm the child
I'm the father
I'm the child
...

Мне разрешено использовать только два канала для связи между процессами.Вот что я написал:

int par_read = pipe1[0];
int par_write = pipe2[1];
int cld_read = pipe2[0];
int cld_write = pipe1[1];

char w;

if (fork()) // par
{
    close(cld_read);
    close(cld_write);

    while(1)
    {
        printf("I'm the father\n");

        if (write(par_write, &w, 1) == -1)
        {
            fprintf(stderr, "Error on par_write: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }

        if (read(par_read, &w, 1) == -1)
        {
            fprintf(stderr, "Error on par_read: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
    }

}
else    // cld
{
    close(par_read);
    close(par_write);

    while(1)
    {
        if (read(cld_read, &w, 1) == -1)
        {
            fprintf(stderr, "Error on cld_read: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }

        printf("I'm the child\n");

        if (write(cld_write, &w, 1) == -1)
        {
            fprintf(stderr, "Error on cld_write: %s\n", strerror(errno));
            exit(EXIT_FAILURE);
        }
    }

Полный код здесь .Проблема в том, что два процесса начинают работать правильно только через несколько сотен строк.Первые строки полны «Я отец».Я тоже проверил подсчет строк:

$ ./ex > ex_out
$ cat ex_out | wc -l
40960
$ cat ex_out | uniq | wc - l
255

Что я делаю не так?

1 Ответ

0 голосов
/ 05 декабря 2018

Вывод printf может не записываться сразу, а задерживаться до тех пор, пока не заполнится буфер, потому что printf и другие функции из stdio.h по умолчанию используют буферизованный вывод.

Попробуйте выполнить одно из следующих действий:

  • добавить setbuf(stdout, NULL); перед fork() для отключения буферизации или
  • использовать fflush(stdout) после printf или
  • использовать write вместо printf.
...