linux应用程序_1_文本浏览器_8_输入设备_3_select机制

linux应用程序_1_文本浏览器_8_输入设备_3_select机制

在以前驱动程序中也有了解倒,轮询机制十分耗费Cpu资源,一般是不使用的

在arm上输入以下命令,开启telnetd服务

telnetd -l /bin/sh

使用远程登陆工具登陆以telnetd方式连接到arm

在telnetd连接界面输入top,即可查看cpu占用率

为解放Cpu,这里引入select机制

select机制与以前驱动程序讲的poll机制是相同的,都是以休眠方式检测文件是否可读、可写、异常、超时,当文件处于这四种状态的任意一种,进程将被唤醒

在轮询机制的基础上修改代码:

输入结构体中添加iFd成员

typedef struct InputOpr{
	char *pcName;

	int  iFd;
	
	int (*InputInit)(void);
	int (*InputExit)(void);
	int	(*InputGetEvent)(PT_InputEventOpr ptInputEventOpr);

	struct InputOpr *ptNext;
}T_InputOpr, *PT_InputOpr;

在具体设备的初始化中设置iFd

static int TsInputInit(void)
{
	char *pcTsdevice=NULL;

	if(! (pcTsdevice = getenv("TSLIB_TSDEVICE"))) 
	{			
		DBG_PRINT("Error at %s ,%d", __FILE__, __LINE__);
		return -1;
	}
	g_ptTs = ts_open(pcTsdevice,1);

	if(!g_ptTs)
	{
		DBG_PRINT("Error at %s ,%d", __FILE__, __LINE__);
		return -1;
	}

	g_tTsInputOpr.iFd = ts_fd(g_ptTs);    //set fd
	
	if (ts_config(g_ptTs)) 
	{
		DBG_PRINT("Error at %s ,%d", __FILE__, __LINE__);
		return -1;
	}

	
	if(GetSeletedDispRes(&g_iXres, &g_iYres))
	{
		DBG_PRINT("Error at %s ,%d", __FILE__, __LINE__);
		return -1;
	}

	return 0;
}
static int StdinInputInit(void)
{
    struct termios tTtystate;
 
    //get the terminal state
    tcgetattr(STDIN_FILENO, &tTtystate);
 
 
    //turn off canonical mode
    tTtystate.c_lflag &= ~ICANON;
    //minimum of number input read.
    tTtystate.c_cc[VMIN] = 1;
       
    //set the terminal attributes.
    tcsetattr(STDIN_FILENO, TCSANOW, &tTtystate);

	g_tStdinInputOpr.iFd = STDIN_FILENO;            //set fd

	return 0;
}

设备初始化时

将需要监视的文件描述符集清空

设置文件描述符集

设置nfds(值为最大文件描述符+1)

int ReallyInputInit(void)
{
	int iError = 1;
	PT_InputOpr ptTmp = g_ptInputOpr;

	FD_ZERO(&g_tRFds);

	while(ptTmp)
	{
		if(ptTmp->InputInit)
		{
			if(!ptTmp->InputInit())
			{
				iError = 0;
				FD_SET(ptTmp->iFd, &g_tRFds);
				if(ptTmp->iFd > g_iFdMax)
					g_iFdMax = ptTmp->iFd;
			}
		}		
		ptTmp = ptTmp->ptNext;
	}
	g_iFdMax++;

	return iError;
}

获取事件:

使用select机制监视输入文件,若可读,则轮询输入结构体

int GetInputEvent(PT_InputEventOpr ptInputEventOpr)
{
	int iError = 1;
	PT_InputOpr ptTmp = g_ptInputOpr;
	fd_set tRFds = g_tRFds;
		
	iError = select(g_iFdMax, &tRFds, NULL, NULL, NULL);

	if(iError < 0)
	{
		DBG_PRINT("select error \r\n");
		return -1;
	}
	else if(!iError)
	{
		return -1;
	}
	
	while(ptTmp)
	{
		if(ptTmp->InputGetEvent)
		{
			iError &= ptTmp->InputGetEvent(ptInputEventOpr);
			if(!iError)
				return 0;		
		}		
		ptTmp = ptTmp->ptNext;
	}

	return -1;
}

在input_manager.c中添加头文件

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
发布了71 篇原创文章 · 获赞 4 · 访问量 7217

猜你喜欢

转载自blog.csdn.net/floatinglong/article/details/86690913