- Если вы не укажете
O_NONBLOCK
, read
будет блокироваться и ждать, пока данные не станут доступны. Так что это не имеет значения; если данные еще не доступны, они будут ждать их.
- Нет, трубы не дуплексные. Если вы хотите двунаправленную связь, вы должны создать два канала (что даст вам всего четыре дескриптора файла).
fildes[0]
всегда означает конец чтения (выходной), а fildes[1]
- конец записи (входной). Таким образом, вы настраиваете один канал точно так же, как вы это сделали (где родитель получает конец записи, а потомок получает конец чтения, чтобы родитель мог отправить дочернему элементу), а другой канал настраивается противоположным образом ( вы позволяете родителю сохранить конец чтения и дать ребенку конец письма).
fildes[0]
и fildes[1]
действительно представляют собой концы трубы, но они не являются взаимозаменяемыми. Один используется для ввода данных «в канал», а другой - для вывода данных «из» канала.
Если вам нужно больше разъяснений, не стесняйтесь спрашивать; Я понимаю, что это может сбить с толку новичков.
Обновление для ответа на вопросы в комментарии:
- Любой процесс может вызвать
pipe()
, и его подпроцессы будут наследовать файловые дескрипторы, которые он получает (если вы не закроете их). То есть они выживают через несколько fork()
вызовов. Таким образом, вы можете написать программу, которая будет передавать файловые дескрипторы внукам, правнукам и т. Д., Если хотите.
- Конечно, два родственных процесса могут общаться следующим образом. Родитель вызывает
pipe()
, чтобы создать пару (или две пары, если вы хотите двунаправленную связь), затем дважды разветвляется. После этого один ребенок может использовать fildes[0]
, а другой ребенок - fildes[1]
. Родитель не должен использовать ни один файловый дескриптор. Вуаля! Общение детей с общим родителем. Примечательно, насколько мощна эта простая (хотя и потенциально неинтуитивная) функция. Это выглядит примерно так, как показано ниже.
- Изображение
fork()
как клонирующая машина. Прежде чем войти в клонирующую машину, вы используете pipe()
, чтобы создать пару подходящих раций, которые используют особую секретную частоту. Можно только передавать; другой может только получить. Когда вы используете клонирующую машину, у вас появляются две копии (оригинал, то есть родитель, и клон, то есть ребенок). В каждой копии теперь есть идентичная пара подходящих раций. Если оригинал уничтожает свое «принимающее» устройство, а клон уничтожает его «передающее» устройство, то оригинал может общаться с клоном с помощью раций (но не наоборот).
Но вы видите, ключевая идея здесь не в том, что pipe()
соединяет два процесса (хотя это его основное использование), а в том, что это что-то, что дублируется во время fork()
. Вы можете повторно войти в клонирующую машину много раз и получить множество раций, поэтому то, что определяет «кто с кем разговаривает» (какие процессы связаны между собой каналом), не является специфическим аспектом функции клонирующей машины или рации.
Скорее, это зависит от того, кто на самом деле использует какие конечные точки, что полностью под вашим контролем. Если бы вы хотели, вы могли бы сделать так, чтобы ребенок закрыл обе конечные точки (уничтожил обе рации), что оставило бы родителя говорить с самим собой (это глупо и, вероятно, бесполезно, но возможно ). Я понимаю, что это немного касательно, но я пытаюсь рассказать, как работает основная идея, чтобы вы поняли сферу вещей, которые возможны с трубами.
Пример родственных процессов, говорящих с трубой (однонаправленный):
int fildes[2];
int status;
status = pipe(fildes);
if (status == -1) { ... }
// first fork
switch (fork()) {
case -1:
// handle error
break;
case 0:
// child 1 (with the writing end -- close the writing end)
close(fildes[0]);
// your logic for child 1 here, using fildes[1] to write
return;
default:
// not child 1: close the writing end
close(fildes[1]);
break;
}
// second fork
switch (fork()) {
case -1:
// handle error
break;
case 0:
// child 2 (with the reading end)
// your logic for child 2 here, using fildes[0] to read
return;
}
// still in the parent
// logic for the common parent here, after forking both children