select 实现IO多路复用

1.select

 int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);
   功能:select用于监测是哪个或哪些文件描述符产生事件;
         有一个或多个同时产生时间返回值。
   参数:nfds:    监测的最大文件描述个数

     readfds:  读事件集合; 
     writefds: 写事件集合;  
     exceptfds:异常事件集合;  
     timeout:超时检测 1
   如果不做超时检测:传 NULL 
   select返回值:<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实现IO多路复用特点

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

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

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

检测鼠标输入事件

​
​
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
    //打开鼠标设备
    int f = open("/dev/input/mouse0", O_RDONLY);
    if (f < 0)
    {
        perror("open mouse err.");
        return -1;
    }
    //1.创建表
    fd_set readfds,tempfds;
    FD_ZERO(&readfds);
    FD_SET(fd,&readfds);
    FD_SET(0,&readfds);

    int maxfd=f;

    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(f);
    return 0;
}

​

​

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值