私は、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);
}