想做一个监控文件的小功能,文件是FIFO类型,可能被写入0或者1,我要做的就是监控这个文件,如果被更新了就把值读出来。
用到select函数,但出现一些不太好理解的现象。
1. 每次select之前,好像都需要设置一下timeout时间,比如下面程序如果把时间设置放在while前,那么将会狂打印"once"。
2. 程序执行时,一开始“once"的打印差不多1s一次。在另一个终端输入:echo -n 0 > has_sd_card 之后,“once"有事疯狂打印了,timeout设置失效了?还是说我的echo -n 0 > has_sd_card导致stdin可读了,但是已经被重定向到文件了,没想明白。
求解答
程序源码如下:
// Linux include
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <stdio.h>
#include <iostream>
int main()
{
int mdevFd = -1;
mdevFd = open("has_sd_card", O_RDONLY|O_NONBLOCK);
if (mdevFd < 0) {
std::cout << "Open file failed." << std::endl;
return -1;
}
std::cout << mdevFd << std::endl;
int ret;
char value;
fd_set rd;
struct timeval tv;
while (true) {
FD_ZERO(&rd);
FD_SET(mdevFd, &rd);
tv.tv_sec = 0;
tv.tv_usec = 1000000; /* timeout 1000 ms */
std::cout << "1" << std::endl;
ret = select(mdevFd + 1, &rd, NULL, NULL, &tv);
std::cout << "2" << std::endl;
if (ret > 0 && read(mdevFd, &value, sizeof(char)) > 0) {
std::cout << "File updated, value = " << value << std::endl;
}
std::cout << "once" << std::endl;
}
close(mdevFd);
return 0;
}