fork() и pipe()

06.01.2018 01:54:38 Просмотров 29 Источник

Есть задание по программировению на С, в UNIX системах:

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

Вот текст программы:

int main(int argc, char *argv[])
{
    int fd[2];
    pid_t pid;
    char buf;
    pipe( fd );

    switch( fork() ){
        case -1:
            perror( "fork()" );
            exit( 1 );
        case 0:
            close(fd[0]);
            while (read(0, &buf, 1) > 0) {
                write(fd[1], &buf, 1);
            }
            write(1, "Death child\n", 12);
            close(fd[1]);
            break;
        default:
            close(fd[1]);
            while (read(fd[0], &buf, 1) > 0) {
                write(1, &buf, 1);
            }
            write(1, "Death parent\n", 12);
            close(fd[0]);
            wait(NULL);
            break;
    }
}

Я его полностью разобрал( внес правки, которые сделали код более понятным, по моему мнению). Но я не могу понять 1.Почему после каждой итерации циклов В child:

while (read(0, &buf, 1) > 0) {
                    write(fd[1], &buf, 1);
                }

В parent:

while (read(fd[0], &buf, 1) > 0) {
                    write(1, &buf, 1);
                }

у меня идет переход на другой процесс ( на родительский или дочерний )? 2.Как избежать бесконечного ожидания родительским процессом чтения из пустого канала?

У вопроса есть решение - Посмотреть?

https://ru.stackoverflow.com/questions/767257/fork-%d0%b8-pipe#comment1194134_767257
упс, ошибка, сейчас исправлю
https://ru.stackoverflow.com/questions/767257/fork-%d0%b8-pipe#comment1194168_767257
...и ещё одна: у вас чтением из канала занимается не родитель, а потомок. И ожидает данных именно он. Второй вопрос выглядит бессмысленным.
https://ru.stackoverflow.com/questions/767257/fork-%d0%b8-pipe#comment1194236_767257
Не, родительский процесс обрабатывается в default, он и читает из иеннованного канала, а вопрос состоит в том как предотвратить ожидане чтения если канал пуст Потом читает из обычного канала ввода read( 0.... )
https://ru.stackoverflow.com/questions/767257/fork-%d0%b8-pipe#comment1194244_767257
А ещё я не вижу в коде использования именованного канала. Именованный существует в файловой системе и доступ к нему осуществляется аналогично доступу к файлам. У вас же в коде просто канал/пайп.
https://ru.stackoverflow.com/questions/767257/fork-%d0%b8-pipe#comment1194245_767257
pipe создает пару файловых описателей, указывающих на запись inode именованного канала ( opennet.ru/man.shtml?topic=pipe&category=2&russian=0 )
https://ru.stackoverflow.com/questions/767257/fork-%d0%b8-pipe#comment1194247_767257
Это ошибка перевода. Откройте оригинал.
https://ru.stackoverflow.com/questions/767257/fork-%d0%b8-pipe#comment1194250_767257
Хмм, да, увидел ошибку, хоть в англе и не секу. Но нам нужно как раз использовать pipe() для межпроцессоного взаимодействия
https://ru.stackoverflow.com/questions/767257/fork-%d0%b8-pipe#comment1194251_767257
Понимаю. Просто указываю на нестыковку в вопросе. Поправьте. (PS: межпроцессного)
https://ru.stackoverflow.com/questions/767257/fork-%d0%b8-pipe#comment1194253_767257
Сейчас исправлю нестыковку

Ответы - fork() и pipe() / fork() и pipe()

Является ответом!
Sergey

09.01.2018 09:34:59

Программа работает абсолютно нормально. Что же касается вопросов:

  1. У меня идет переход на другой процесс ( на родительский или дочерний )?
  2. Как избежать бесконечного ожидания родительским процессом чтения из пустого канала?

То они ставят в тупик... В памяти вашего компа ОДНОВРЕМЕННО присутствуют два процесса. Какой из них выполняется каким именно процессором и в какое время - это решает ядро операционки.

Если процесс не готов к выполнению (например - ждёт ввода), то он висит. Какой процесс первым придёт в готовность, тот и продолжит своё выполнение.

Вот и весь преход... С точки зрения ядра - абсолютно не важно, родительский, или дочерний.

А насчёт ввода из пустого канала - это Вы вообще - как представляете?! Если канал пуст, как из него можно что-то ввести? Вот программа и висит на операции read.

Закрыть X