2015-10-05 1 views
1

Я хочу сделать трубку между создателем-потомком и родительским читателем в C. Я думал, что мой родительский процесс должен будет дождаться, пока его ребенок напишет в буфере, прежде чем он сможет его прочитать, но затем я хотел, чтобы проверить его, так что я написал следующий фрагмент кода:Достаточно ли чтение() в родительском процессе для записи write() в трубке?

pipe(fd); 
// ... checks for pipe 
pid_t pid = fork(); 
// ... checks for fork 
if (pid == 0) { 
    close(fd[0]); 
    // Long sleep hoping parent will terminate before the write() 
    sleep(10); 
    write(fd[1], "hello", strlen("hello") + 1); 
    close(fd[1]); 
} else { 
    close(fd[1]); 
    read(fd[0], buf, sizeof(buf)); 
    printf("received: %s\n", buf); 
    close(fd[0]); 
} 
return 0; 

выход неожиданно (или нет?) received: hello. Тот же выход, если я заменил вызов sleep() на цикл for (volatile int i = 0; i < some_big_int; ++i);. Я не думаю, что вызов read() заблокирует мой родительский процесс, пока ребенок не напишет на другом конце канала, но я не могу объяснить это поведение. Любой намек?

+1

Это ожидаемая операция: I.E. 'read()' blocks, будут возвращены на общем количестве запрошенных байтов, или eof встречается. Или некоторые события и сигналы ошибки – user3629249

+0

Я не могу найти, где это сказано в 'man 2 read': например. это предложение, по-видимому, указывает на то, что если читать нечего, read() возвращает и не блокирует: 'В отсутствие каких-либо ошибок или если read() не проверяет наличие ошибок, read() со счетом 0 возвращает ноль и не имеет других эффектов. ' – hdl

+1

Когда' read' передается ненулевое 'count' на потоковой fd (например, на трубе), он блокируется до тех пор, пока не будет доступно по крайней мере 1 байт, тогда читается столько же' count', как это может быть в то время. Поскольку вы «пишете» и «закрываете» (а запись меньше, чем 'PIPE_BUF'), она сразу же смывает всю строку, поэтому, когда она разблокируется, она получает все то, что вы написали сразу. – ShadowRanger

ответ

2

read будет блокироваться, пока не будет прочитан хотя бы один байт, или он встретит ошибку или достигнет конца потока. Когда есть хотя бы один байт для чтения, он будет считывать столько байтов, сколько может (до максимального указанного вами числа), а затем возвращаться.

В этом случае вызов родительского процесса в read будет блокироваться до тех пор, пока дочерний процесс не обработает сообщение.


От man 7 pipe секции ввода/вывода на трубах и FIFOs:

Если процесс пытается прочитать из пустой трубы, а затем читать (2) будет блокировать, пока данные не доступны. Если процесс пытается записать в полный канал (см. Ниже), тогда напишите (2) блоки до тех пор, пока достаточное количество данных не будет считано из канала, чтобы дать возможность выполнить запись. Неблокирующий ввод-вывод возможен с помощью операции fcntl (2) F_SETFL, чтобы включить флаг состояния открытого файла O_NONBLOCK.

+0

Где это указано? К сожалению, я не нашел эту информацию ни в «man 2 pipe», ни в 'man 2 read' – hdl

+0

Нашел ее в' man 7 pipe' и отредактировал ваш ответ соответственно. Большое спасибо. – hdl

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

  • Нет связанных вопросов^_^