select函数中的坑(C语言)

林祯
2023-12-01

最近写了一个测试驱动的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]);
			}
		}
		
	}
}

 类似资料: