13

パイプを想定して、

int pipe_fd[2];
pipe(pipe_fd);

フォークし、1つのプロセスが任意の時間にパイプに書き込むことを期待します。プロセスの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
}
4

3 に答える 3

14

read文字がなくなっても0を返さないという点で、ロジックが間違っています。代わりに、ファイルを非ブロックモードにしない限り、さらに受信するまでブロックしますが、その後-1を返し、 0を返すか、または返すのではなく設定errnoします。0を返すことができるのは、size引数が0またはファイルの終わりに達しました。また、パイプの場合、ファイルの終わりはパイプの書き込み端が閉じられていることを意味します。まだ入力がないという理由だけで、ファイルの終わりのステータスは発生しません。EWOULDBLOCKEAGAINread

そうは言っても、チェックする最も簡単な方法は次のとおりです。

if (poll(&(struct pollfd){ .fd = fd, .events = POLLIN }, 1, 0)==1) {
    /* data available */
}

ただし、ノンブロッキングモードを使用している場合を除き、すべての読み取り操作の前にこのチェックを行う必要があります。read一度に1バイトずつ実行するのではなく、より大きなバッファーをに渡すと、チェックのコストのほとんどが排除されます。

于 2012-12-11T00:26:31.017 に答える
4

この関数で読み取るデータがあるかどうかを確認でき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 [...]

お役に立てば幸いです。

于 2012-12-11T00:35:27.740 に答える
2

R ..の答えは良いですが、pollは、「revents」にフラグが設定されているファイル記述子構造体の数を返します。から読み取ることができる場合は1になりますfdが、エラーフラグのいずれかが設定されている場合も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;
}
于 2018-11-19T09:12:00.493 に答える