最近寫了一個測試驅動的poll函數的應用程序,在應用層中調用select進行操作,設置好timeout之後,如果只對select()調用一次,就沒有問題。但一旦多次調用後,就變成只有第一次timeout有效,後面的都沒有效果了。
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <unistd.h>
int main(int argc , char ** argv)
{
int i;
int fd;
int ret;
int press_cnt[4];
fd_set rfds;
struct timeval time;
time.tv_sec = 5; //5s
fd = open("/dev/buttons", O_RDWR); //打開設備
if(fd<0)
{
printf("Can't open");
return -1;
}
while(1)
{
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
ret = select(fd + 1, &rfds, NULL, NULL, &time);
if (!ret)
{
printf("time out\n");
}
else
{
read(fd, press_cnt, sizeof(press_cnt)); //讀取值到press_cnt緩存區,讀取長度sizeof(press_cnt)
for(i = 0 ; i<sizeof(press_cnt)/sizeof(press_cnt[0]);i++)
{
if(press_cnt[i]) //如果按下次數不爲0,打印出來
printf("K%d has been pressed %d times \n", i+1, press_cnt[i]);
}
}
}
}
後來查看了select()源碼,發現它會把timeout更新爲0,所以每次調用select(), 都要重新對timeout進行賦值。
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <unistd.h>
int main(int argc , char ** argv)
{
int i;
int fd;
int ret;
int press_cnt[4];
fd_set rfds;
struct timeval time;
//time.tv_sec = 5; //5s
fd = open("/dev/buttons", O_RDWR); //打開設備
if(fd<0)
{
printf("Can't open");
return -1;
}
while(1)
{
time.tv_sec = 5; //5s
time.tv_usec = 0;//select函數會不斷修改timeout的值,所以每次循環都應該重新賦值[windows不受此影響]
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
ret = select(fd + 1, &rfds, NULL, NULL, &time);
if (!ret)
{
printf("time out\n");
}
else
{
read(fd, press_cnt, sizeof(press_cnt)); //讀取值到press_cnt緩存區,讀取長度sizeof(press_cnt)
for(i = 0 ; i<sizeof(press_cnt)/sizeof(press_cnt[0]);i++)
{
if(press_cnt[i]) //如果按下次數不爲0,打印出來
printf("K%d has been pressed %d times \n", i+1, press_cnt[i]);
}
}
}
}