Хрестоматия по программированию на Си в Unix



Системные вызовы и взаимодействие с UNIX. Хрестоматия по программированию на Си в Unix - стр. 5


а стандартный ввод B - из канала conn[0]

dup2(conn[0], 0); close(conn[0]); read(0, ... ); /* или gets */

Это соответствует конструкции

$ A | B

записанной на языке СиШелл.

Файл, выделяемый под pipe, имеет ограниченный размер (и поэтому обычно целиком оседает в буферах в памяти машины). Как только он заполнен целиком - процесс, пишущий в трубу вызовом write, приостанавливается до появления свободного места в трубе. Это может привести к возникновению тупиковой ситуации, если писать программу неаккуратно. Пусть процесс A является сыном процесса B, и пусть процесс B издает вызов wait, не закрыв канал conn[0]. Процесс же A очень много пишет в трубу conn[1]. Мы получаем ситуацию, когда оба процесса спят:

A потому что труба переполнена, а процесс B ничего из нее не читает, так как ждет окончания A;

B потому что процесс-сын A не окончился, а он не может окончиться пока не допишет свое сообщение.

Решением служит запрет процессу B делать вызов wait до тех пор, пока он не прочитает ВСЮ информацию из трубы (не получит EOF). Только сделав после этого close(conn[0]); процесс B имеет право сделать wait.

Если процесс B закроет свою сторону трубы close(conn[0]) прежде, чем процесс A

закончит запись в нее, то при вызове write в процессе A, система пришлет процессу A

сигнал SIGPIPE - "запись в канал, из которого никто не читает".

6.6.1. Открытие FIFO файла приведет к блокированию процесса ("засыпанию"), если в буфере FIFO файла пусто. Процесс заснет внутри вызова open до тех пор, пока в буфере что-нибудь не появится.

Чтобы избежать такой ситуации, а, например, сделать что-нибудь иное полезное в это время, нам надо было бы опросить файл на предмет того - можно ли его открыть? Это делается при помощи флага O_NDELAY у вызова open.

int fd = open(filename, O_RDONLY|O_NDELAY);

Если open ведет к блокировке процесса внутри вызова, вместо этого будет возвращено значение (-1). Если же файл может быть немедленно открыт - возвращается нормальный дескриптор со значением >=0, и файл открыт.




Содержание  Назад  Вперед