C - Как видеть, что труба пуста
при условии, что труба,
int pipe_fd[2];
pipe(pipe_fd);
Мы видим, что один процесс будет записываться в трубу в произвольное время. В одном из процессов мы хотим иметь возможность проверять содержимое трубы без блокировки.
то есть. Хотя типичное чтение будет блокироваться, если ничего не присутствует, и конец записи остается открытым. Я хочу пойти делать другие вещи и, возможно, даже немного почитать немного, сделать некоторые вещи, а затем проверить, чтобы увидеть, есть ли еще, a la:
close(pipe_fd[1]);
while(1){
if(/**Check pipe contents**/){
int present_chars = 0;
while( read(pipe_fd[0],&buffer[present_chars],1) != 0)
++present_chars;
//do something
}
else
//do something else
}
Спасибо заранее!
Ответы
Ответ 1
Ваша логика ошибочна в том, что read
не вернет 0, когда закончится символ; вместо этого он будет блокироваться до тех пор, пока он не получит больше, если вы не поместите файл в неблокирующий режим, но затем он вернет -1 и установите errno
в EWOULDBLOCK
или EAGAIN
вместо того, чтобы возвращать 0. Единственное время read
может когда-либо возвращать 0, когда аргумент размера был равен 0 или конец файла. И для труб конец файла означает, что конец записи трубы закрыт; статус конца файла не возникает только потому, что еще нет доступных данных.
С учетом сказанного, самый простой способ проверить:
if (poll(&(struct pollfd){ .fd = fd, .events = POLLIN }, 1, 0)==1) {
/* data available */
}
но если вы используете неблокирующий режим, вам необходимо выполнить эту проверку перед каждой отдельной операцией чтения. Передача большего буфера в read
вместо того, чтобы делать это, byte-at-time устранит большую часть затрат на проверку.
Ответ 2
Вы можете проверить, есть ли данные для чтения с помощью функции read()
. От read(3)
:
When attempting to read from an empty pipe or FIFO:
* If some process has the pipe open for writing and
O_NONBLOCK is set, read() shall return -1 and set
errno to [EAGAIN].
* If some process has the pipe open for writing and
O_NONBLOCK is clear, read() shall block the calling
thread until some data is written or the pipe is
closed by all processes that had the pipe open for
writing.
The read() function shall fail if:
EAGAIN or EWOULDBLOCK
The file descriptor is for a socket, is marked
O_NONBLOCK, and no data is waiting to be received.
Итак, если вы установите O_NONBLOCK
, вы сможете сказать, что что-то нужно читать на трубе, просто называя read()
.
Напоминаем, что от open(3)
:
SYNOPSIS
int open(const char *path, int oflag, ... );
DESCRIPTION
Values for oflag are constructed by a
bitwise-inclusive OR of flags from the following
list, defined in <fcntl.h>. Applications shall
specify exactly one of the first three values
(file access modes) below in the value of oflag:
O_NONBLOCK [...]
Надеюсь, это поможет.