select事件的应用

大家好,这里是石侃侃的博客,这篇文章介绍了select机制在节省cpu资源上的用途,和多线程相比,它应用更加简单灵活

对于select / poll 机制的原理,参考大牛的博客 :https://blog.csdn.net/vonzhoufz/article/details/44490675

在这里介绍的是select的一般用法

    

    总的来说机制原理较为复杂 , 但是用户API非常简单  只需要调用select(int nfds,    fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout)函数

用途 :
监测多个文件,只要有某一个文件可读/可写/异常或超时,即返回
 int select(int nfds,    fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
                最大文件句柄+1   被监测是否可读的文件                                         超时时间
                                                              被监测是否可写的文件
                                                                                       被监测是否有异常的文件
 
int nfds :
关于句柄的一些理解和整理  感谢qqID : 过去的都过去了,仅供参考 : 柄就和把手一样,你一拉就可以提起一些东西,句柄你也可以通过它得到一些东西,比如说数据,一般是索引类的东西  ;
比如这里也是一个索引 比如说文件描述符,代表你当前进程打开的文件,你连续打开的文件   
这里可以看作文件描述符+1。固定的文件有固定的文件描述符  以此来判断对哪个(那些)文件做出响应  
百科 : 文件描述符 :内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。
fd = open(path, O_CREAT | O_RDONLY, 0644);  即为fd ;

返回值 :
执行成功则返回文件描述词状态已改变的个数,如果返回0代表在描述词状态改变前已超过超时时间,没有返回;当有错误发生时则返回-1
fd_set *readfds  : 
一旦有输入则返回   一个fd_set是一个固定大小的缓冲区。 执行FD_CLR()或FD_SET(),其值为负值或等于或大于FD_SET-SIZE的值fd将导致未定义的行为。 而且,POSIX要求fd是一个有效的文件描述符。  
struct timeval *timeout参数情况:  
如果参数超时设为:NULL,则表示选择()没有超时,选择将一直被阻塞,直到某个文件描述符上发生了事件。
0:仅检测描述符集合的状态,然后立即返回,并不等待外部事件的发生。特定的时间值:如果在指定的时间段里没有事件发生,选择将超时返回。

下面的宏提供了处理这三种描述词组的方式:
FD_CLR(inr fd,fd_set* set);用来清除描述词组set中相关fd 的位
FD_ISSET(int fd,fd_set *set);用来测试描述词组set中相关fd 的位是否为真  
FD_SET(int fd,fd_set*set);用来设置描述词组set中相关fd的位
FD_ZERO(fd_set *set);用来清除描述词组set的全部位
常见的程序片段如下:
fs_set readset;
FD_ZERO(&readset);
FD_SET(fd,&readset);
select(fd+1,&readset,NULL,NULL,NULL);

if(FD_ISSET(fd,readset){……}

功能源代码:触摸屏的select机制实现输入唤醒 

 

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

/**********************************************************************
 * 函数名称: main
 * 功能描述: select实现低cpu占用操作 触摸屏输入事件监测
 * 输入参数: 无
 * 输出参数: 无
 * 返 回 值: 0 - 成功, 其他值 - 失败
 * 修改日期        版本号     修改人	      修改内容
 * -----------------------------------------------
 * 2018/04/17	     V1.0	  石侃侃	      创建
 * 存在问题: select(fd+1, &rfds, NULL, NULL, &tv);  目前已经实现碰触触摸屏唤醒 (select返回)
			 但是无法识别可读可写 (&rfds在第二第三个参数都有效)而且不能判断open打开的txt文本文件 
 ***********************************************************************/
	main(void)
	{   
		
	   fd_set rfds;
	   struct timeval tv;
	   int retval;
		
	   int fd; 

	   fd=open("/dev/input/event0",O_RDONLY); /* 触摸屏设备 */
	   /* Watch stdin (fd 0) to see when it has input. */
	   FD_ZERO(&rfds);
	   FD_SET(fd, &rfds);

	   /* Wait up to five seconds. */
	   tv.tv_sec = 5;
	   tv.tv_usec = 0;

	   retval = select(fd+1, &rfds, NULL, NULL, &tv);/* 超时或者有输入则返回 */
	   /* Don't rely on the value of tv now! */

	   if (retval == -1)
		   perror("select()");
	   else if (retval)
	   {
			if(FD_ISSET(fd,&rfds))  
			{  
				printf("Data is available now   ok.\n");
				printf("retval=%d\n",retval); 
			}
			else   
			{
				printf("FD_ISSET error");  
			}  


		   }
	   else
		   printf("No data within five seconds.\n"); /* retval=0 */
	  return 0;
	}

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页