我对Linux上的fifo
有些陌生,对select()
的使用经验也很少。
我learned在FIFO的读端调用open()
将阻塞,直到写端完成管道。
可以使用O_NONBLOCK
打开fifo的读取结束,以便不会阻止open()
。然后,您可以使用readfds中的fifo文件描述符select()
来了解文件何时可以打开 - 是吗?
我现在感到困惑的是:在知道文件可以打开之后,我随后想知道fifo具有可读内容,即我想知道read()
fifo文件描述符不会阻塞。为此,我会考虑使用readfds中的fifo文件描述符select()
- 但这似乎与使用select()
来判断该文件是否可打开相冲突。
所以我想总结一下我的问题:如何使用select()
知道1)当fifo的读取端的open()
不会阻塞时,以及2)何时read()
在fifo上不会阻止?
答案 0 :(得分:0)
我假设select()
在读取端解除锁定以指示fifo是可打开的,这似乎是不正确的。只有当要在fifo中读取数据时,看起来select()
才会在读取端解锁。
此测试代码演示了我的观察结果: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 );
}