我假设select() 在读取端解除阻塞以表明先进先出是可打开的,这似乎是不正确的。看起来select()只有在fifo中有数据要读取时才会在读取端解除阻塞。
这个测试代码证明了我的观察:select() 超时;取消注释单个注释行,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 );
}