2017-10-27 19 views
0

私はfifoをLinux上で少し新しくしましたが、select()の経験も限られています。fifo openableと読み取り可能なコンテンツを区別するにはどうすればよいですか?

learned私はFIFOのリードエンドでopen()を呼び出すと、ライトエンドでパイプが完了するまでブロックされます。

open()でブロックされないように、fifoの読み出し側をO_NONBLOCKで開くことができます。ファイルがオープン可能であることを知るためには、readfds内のFIFOのファイル記述子をselect()にすることができます。

ファイルがオープン可能であることを知った後、私はFIFOが読み取り可能な内容を持っていることを知りたいと思っています。つまり、FIFOファイルディスクリプタのread()ブロックされません。このためには、私はとfifoファイル記述子をreadfdsで考えていたでしょうが、これはselect()を使ってファイルがオープン可能かどうかを知ることと矛盾するようです。どのように私はブロックされませんFIFOの読み出し側に1)ときopen()を知るためにselect()を使用することができ、及び2)ときread() FIFOにブロックしないでしょう。

だから私は私の質問を要約すると思いますか?

答えて

0

私は、select()はFIFOがオープン可能であることを示すために読み取り側でブロックを解除すると誤っているように見えます。 select()のように見えるのは、FIFO内で読み込むデータがある場合に限り、読み込み終了時にブロックを解除します。

このテストコードは、私の所見を示しています。つまり、select()はタイムアウトします。 1つのコメント行をコメント解除し、select()はfifoファイル記述子のブロックを解除します。

#include <iostream> 
#include <pthread.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <sys/select.h> 
#include <ctime> 

#define FIFO "/tmp/foo" 

void* sr1(void* arg) 
{ 
    mkfifo(FIFO, 0777); 
    sleep(3); 
    int fd = open (FIFO, O_WRONLY); 
    //write(fd, "a", 1); 
    std::cout << "t1 opened " << fd << std::endl; 
    sleep(3); 
    close(fd); 
    std::cout << "t1 closed " << fd << std::endl; 
    return NULL; 
} 

void* sr2(void* arg) 
{ 
    int fd = open(FIFO, O_RDONLY | O_NONBLOCK); 
    std::cout << "t2 opened " << fd << std::endl; 
    fd_set readfds; 
    FD_ZERO(&readfds); 
    FD_SET(fd, &readfds); 
    struct timeval ts = { 5, 0 }; 
    std::cout << "t2 waiting now" << std::endl; 
    select(fd + 1, &readfds, NULL, NULL, &ts); 
    if (FD_ISSET(fd, &readfds)) 
    { 
    std::cout << "t2 " << fd << " set so select() unblocked" << std::endl; 
    } 
    else 
    { 
    std::cout << "t2 " << " select() unblocked at timeout" << std::endl; 
    } 
    close(fd); 
    std::cout << "t2 closed " << fd << std::endl; 
    return NULL; 
} 

int main(int argc, char* argv[]) 
{ 
    pthread_t t1; 
    pthread_t t2; 

    pthread_create(&t1, NULL, sr1, NULL); 
    pthread_create(&t2, NULL, sr2, NULL); 

    pthread_join(t1, NULL); 
    pthread_join(t2, NULL); 
} 
関連する問題