1、Linux select 函数
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
nfds 最大文件fd + 1
readfds 监听可读文件集合fd
writefds 监听可写文件集合fd
exceptfd 监听异常文件集合fd
timeout 超时时间
2、函数实例
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <unistd.h>
#include <sys/select.h>
#include <string.h>
static char * eventTypeToString(__u16 type){
switch(type){
case EV_SYN:
return "EV_SYN";
case EV_KEY:
return "EV_KEY";
case EV_REL:
return "EV_REL";
case EV_ABS:
return "EV_ABS";
case EV_MSC:
return "EV_MSC";
case EV_SW:
return "EV_SW";
default:
return "UNKOWN";
}
}
static char * eventCodeToString(__u16 code){
switch(code){
case KEY_ESC:
return "KEY_ESC";
case KEY_POWER:
return "KEY_POWER";
default:
return "UNKOWN";
}
}
int main (int argc, char ** argv){
int fd;
/*需要轮询的fds*/
fd_set readfds;
/*需要轮询的fds数量*/
int maxfds;
struct input_event event;
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
if(argc != 2){
printf("Usage: %s <dev> \n", argv[0]);
}
fd = open(argv[1], O_RDWR | O_NONBLOCK);
if(fd < 0){
printf("open %s err = %s\n", argv[1],strerror(errno));
return 0;
} else {
printf("open %s success \n",argv[1]);
}
//清零
FD_ZERO(&readfds);
/*将标准输入的文件描述符添加到集合中, 如果是多个添加多个文件描述符*/
FD_SET(fd, &readfds);
maxfds = fd + 1; //最大文件描述符fd + 1
while(1){
int ret = select(maxfds, &readfds, NULL, NULL, NULL);
if(ret > 0){
/*只有发生过的fd才会在文件readfds中*/
if(FD_ISSET(fd, &readfds)){
while(read(fd, &event, sizeof(event)) == sizeof(event)){
printf("get envent: type = 0x%x, Code = 0x%x value = 0x%x \n",event.type, event.code, event.value);
printf("get envent: type = %s, Code = %s value = 0x%x \n",eventTypeToString(event.type), eventCodeToString(event.code), event.value);
}
}
//将文件描述符重置
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
} else if (ret == 0){
if(FD_ISSET(fd, &readfds)){
printf("select time out \n");
}
} else {
perror("poll err \n");
}
}
return 0;
}
3、代码运行效果
编译二进制文件,运行到手机端