只读方式打开文件和可读可写打开对select的影响
为什么O_RDONLY方式打开的文件 和O_RDWR方式都是读管道文件 一个可以返回wait....一个却没有为什么?
下面是代码
// 使用 select 监听有名管道,当有名管道有数据时,读取数据并打印
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define FIFO_NAME "./fifo"
int main(void)
{
int ret,frd;
fd_set readfds,tmpfds;
struct timeval tv = {3,0},tmp_tv;
char buffer[64] = {0};
frd = open(FIFO_NAME,O_RDONLY);
FD_ZERO(&readfds);
FD_ZERO(&tmpfds);
FD_SET(frd,&readfds);
for(;;){
tmp_tv = tv;
tmpfds = readfds;
ret = select(frd+1,&tmpfds,NULL,NULL,&tmp_tv);
sleep(1);
if (ret == -1){
perror("[ERROR] select(): ");
exit(EXIT_FAILURE);
}else if(ret==0){
printf("waiting...\n");
}else if (ret > 0){
if (FD_ISSET(frd,&tmpfds)){ // 判断是否在集合中
memset(buffer,0,sizeof(buffer));
ret=read(frd,buffer,sizeof(buffer));
if (frd== -1){
perror("[ERROR] dest fopen(): ");
close(frd);
return -1;
}
printf("%s",buffer);
}
}
}
close(frd);
return 0;
}
正在回答 回答被采纳积分+1
重新解释一下,管道本身带有阻塞的属性,阻塞有两个前提:
1)管道文件不能以O_RDWR方式打开,那样的话会失去阻塞属性,自己写自己读那就不需要阻塞;
2)在1的前提下,管道文件以O_RDONLY方式打开且没有数据会导致函数read()阻塞;
既然你这里用了select( ),目标就是非阻塞方式监听多个文件的可读事件。所以不应该让管道文件frd阻塞,要么使用O_RDWR打开,要么使用O_RDONLY|O_NONBLOCK打开。建议使用后者,更符合实际项目。
换句话说如果你让frd带上了阻塞属性,那么select( )内部探测frd是不是可读的时候就已经阻塞了,配置的第4参数就没有超时效果了,管道又没有数据,函数select( )自然就不会超时返回了,也就不会有超时打印wait...。
顺带说一下,函数select( )的第4个参数就是超时控制的,不需要后面跟一个sleep(1)。
- 参与学习 394 人
- 提交作业 23325 份
- 解答问题 1188 个
行业热门,政策风口,人才缺口极大,现在入场时机正好! 上千人检验,数轮迭代的硬核知识体系,软硬件通吃 保姆式教学+简历指导+1V1模拟面试+3次内推,助力轻松就业!
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星