パイプを想定して、
int pipe_fd[2];
pipe(pipe_fd);
フォークして、1つのプロセスが任意の時間にパイプに書き込むことを期待します。あるプロセスでは、パイプの内容をブロックせずにチェックできるようにする必要があります。
つまり、通常の読み取りは、何も存在せず、書き込み終了が開いたままの場合にブロックされます。私は他のことをしたいのですが、一度に少しずつ読んで、いくつかのことをしてから、もう一度チェックして、もっとあるかどうかを確認したいと思います。
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
}
read
が文字を使い果たしても0を返さないという点で、ロジックが間違っています。代わりに、ファイルを非ブロックモードにしない限り、さらに受信するまでブロックしますが、その後-1を返し、errno
をEWOULDBLOCK
またはEAGAIN
に設定します。 0を返すのではなく。read
がever 0を返すことができるのは、size引数が0であるか、ファイルの終わりに達したときだけです。そして、パイプの場合、ファイルの終わりは、パイプの書き込み終了が閉じられたことを意味します。利用可能な入力がまだないという理由だけで、ファイルの終わりステータスは発生しません。
そうは言っても、チェックする最も簡単な方法は次のとおりです。
if (poll(&(struct pollfd){ .fd = fd, .events = POLLIN }, 1, 0)==1) {
/* data available */
}
ただし、ノンブロッキングモードを使用している場合を除き、すべての読み取り操作の前にこのチェックを行う必要があります。一度に1バイトずつ行うのではなく、より大きなバッファをread
に渡すと、チェックのコストのほとんどが排除されます。
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 [...]
_
お役に立てば幸いです。
R ..の答えは良いですが、pollは、「revents」にフラグが設定されているファイル記述子構造体の数を返します。 fd
から読み取ることができる場合は1になりますが、エラーフラグのいずれかが設定されている場合も1になります。これは、R ..の答えは、パイプがエラー状態になった場合に読み取り可能であると言うことを意味します。より堅牢なチェックは次のようになります。
bool canReadFromPipe(){
//file descriptor struct to check if POLLIN bit will be set
//fd is the file descriptor of the pipe
struct pollfd fds{ .fd = fd, .events = POLLIN };
//poll with no wait time
int res = poll(&fds, 1, 0);
//if res < 0 then an error occurred with poll
//POLLERR is set for some other errors
//POLLNVAL is set if the pipe is closed
if(res < 0||fds.revents&(POLLERR|POLLNVAL))
{
//an error occurred, check errno
}
return fds.revents&POLLIN;
}