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>