在linux中通过select实现IO多路复用对鼠标及键盘输入的同时检测

在程序中经常会需要同时处理多路输入输出流,采用阻塞的方法会无法达成想要的效果,而采用不阻塞的方法时需要对多个输入输出信号不停的轮询会太浪费cpu时间。如果采用线程或进程的方法将产生线程或进程之间的同步与通信问题这会使程序变得复杂。解决问题相对较好的解决方法就是利用select函数。

selec函数原型:
int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

参数:

nfds:监测的最大文件描述个数

readfds: 读事件集合

writefds: 写事件集合,传NULL表示不关心

exceptfds:异常事件集合;

timeout:超时检测 1

如果不做超时检测:传 NULL

返回值:

<0 出错

>0 表示有事件产生;

如果设置了超时检测时间:&tv

select返回值:

<0 出错

>0 表示有事件产生;

==0 表示超时时间已到;

结构体:
struct timeval 
{
    long    tv_sec;         /* seconds */
    long    tv_usec;        /* microseconds */
};
相关函数:           
void FD_CLR(int fd, fd_set *set);//将fd从表中清除
int  FD_ISSET(int fd, fd_set *set);//判断fd是否在表中
void FD_SET(int fd, fd_set *set);//将fd添加到表中
void FD_ZERO(fd_set *set);//清空表
select函数的特点:

1. 一个进程最多只能监听1024个文件描述符 。

2. select被唤醒之后需要重新轮询一遍驱动的poll函数,效率较低。

3. select每次会清空表,每次都需要拷贝用户空间的表到内核空间,效率较低。

利用select函数实现对键鼠的信号检测:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
int main(int argc, char const *argv[])
{
    //打开鼠标设备
    int fd = open("/dev/input/mouse0", O_RDONLY);//在终端利用sudo cat /dev/input/mouse0
语句检测自己的鼠标位置
    if (fd < 0)
    {
        perror("open mouse err.");
        return -1;
    }
    //select 实现同时响应终端输入和鼠标输入
    //1.创建表
    fd_set readfds,tempfds;
    //清空表
    FD_ZERO(&readfds);
    //2.将关心的文件描述符添加到表中
    FD_SET(fd,&readfds);
    FD_SET(0,&readfds);
    int maxfd=fd;
    char buf[128];
    int ret;
    while(1)
    {
        //3.调用select函数检测事件
        tempfds=readfds;
        ret=select(maxfd+1,&tempfds,NULL,NULL,NULL);
        if(ret < 0)
        {
            perror("select err.");
            return -1;
        }
        //终端输入
        if(FD_ISSET(0,&tempfds))
        {
         fgets(buf,sizeof(buf),stdin);
         printf("key:%s\n",buf);
        }
        //鼠标输入
        if(FD_ISSET(fd,&tempfds))
        {
         int ret=read(fd,buf,sizeof(buf));
         printf("mouse:%s\n",buf);
        }
    }
    close(fd);
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值