欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > Linux系统驱动(八)IO模型---IO多路复用(未整理)

Linux系统驱动(八)IO模型---IO多路复用(未整理)

2025/9/25 17:09:50 来源:https://blog.csdn.net/weixin_44254079/article/details/140971577  浏览:    关键词:Linux系统驱动(八)IO模型---IO多路复用(未整理)

文章目录

  • 一、IO多路复用
    • (一)概念
      • 1. 实现机制
      • 2. 使用示例
    • (二)IO多路复用实现原理
    • (三)epoll函数
      • 1. select/poll/epoll的区别
      • 2. API
      • 2. 使用示例

一、IO多路复用

(一)概念

在一个应用程序中如果需要同时监听多个文件描述符对应的数据时,就需要使用IO多路复用模型,IO多路复用有select/poll/epoll方式。

将需要监听的文件描述符放到读表中,让后使用select统一监听,如果所有的文件描述符对应的数据都没有就绪进程休眠。如果有一个或者多个硬件数据就绪select对应的进程就会被唤醒,然后从就绪的读表中找出就绪的文件描述符,然后调用read函数将数据读取到用户空间即可。

1. 实现机制

US:fd_set rfds; //定义读取表fd1 = open("/dev/mycdev0",O_RDWR);fd2 = open("/dev/input/event1",O_RDWR);while(1){FD_ZERO(&rfds); //清空读表FD_SET(fd1,&rfds);//将fd1放到读表中FD_SET(fd2,&rfds); //将fd2放到读表中select(fd2+1,&rfds,NULL,NULL,NULL);if(FD_ISSET(fd1,&rfds)){ //fd1就绪read(fd1,buf1,sizeof(buf1));printf("buf1 = %s\n",buf1);}if(FD_ISSET(fd2,&rfds)){ //fd2就绪read(fd2,buf2,sizeof(buf2));printf("buf2 = %s\n",buf2);}}
---------------------------------------------------------
KS:file_operations:
//__poll_t (*poll) (struct file *, struct poll_table_struct *);
__poll_t mycdev_poll(struct file *file, struct poll_table_struct *wait)
{//1.调用poll_waitpoll_wait(file,等待队列头,wait);//2.判断数据是否就绪if(condition)return EPOLLIN;  //EPOLLIN数据可读,EPOLLOUT数据可写return 0;
}
  • 注:
  • EPOLLIN —数据可读
  • EPOLLOUT ----数据可写

2. 使用示例

mydev.c


  • 注:select

(二)IO多路复用实现原理

current|
#define current get_current()
#define get_current() (current_thread_info()->task)|
struct thread_info {struct task_struct	*task;}|
struct task_struct {pid_t pid;struct files_struct	 *files;
}|
//linux-5.10.61/include/linux/fdtable.h
struct files_struct {struct file __rcu * fd_array[NR_OPEN_DEFAULT];}|
struct file{
}

current在内核中指代当前进程
task_struct结构体里记录fd
进程与进程之间的fd互不影响

(三)epoll函数

1. select/poll/epoll的区别

  • select(表)
    select监听的最大文件描述符个数是1024
    select会有清空表的过程,需要反复构造表,反复拷贝表,效率比较低
    select对应的进程从休眠态被唤醒后,需要再次遍历文件描述符表,效率比较低
  • poll(链表)
    poll监听的文件描述符没有个数限制
    poll没有清空表的过程,不需要反复构造表,反复拷贝表,效率比较高
    poll对应的进程从休眠态被唤醒后,需要再次遍历文件描述符表,效率比较低
  • epoll(红黑树(完全二叉树)+双向链表)------ 红黑树保存要监听的fd,双向链表保存就绪的fd
    epoll监听的文件描述符没有个数限制
    epoll没有清空表的过程,不需要反复构造表,反复拷贝表,效率比较高
    epoll对应的进程从休眠态被唤醒后,不需要再次遍历文件描述符表,能直接拿到就绪的文件描述符,效率比较高

2. API

#include <sys/epoll.h>
int epoll_create(int size);
功能:参数:@size:无意义,但是必须填写大于0的值返回值:成功返回epfd;失败返回-1,重置错误码
//这个函数本质就是创建一个红黑树,用户通过epfd拿到红黑树,这个epfd也会占用一个fd值int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
功能:参数:@epfd@op:操作方式EPOLL_CTL_ADD	添加EPOLL_CTL_MOD	修改EPOLL_CTL_DEL	删除@fd:被操作的文件描述符@event:事件类型返回值:成功返回0;失败返回-1,置位错误码int epoll_wait(int epfd, struct epoll_event *revents, int maxevents, int timeout);
功能:
参数:@epfd@revents@maxevents@timeout:超时时间=0	:立即返回>0	:=-1	:忽略超时,永久阻塞,直到有fd就绪
返回值:成功,返回就绪的文件描述符的个数;返回0,代表超时,没有文件描述符就绪失败,返回-1,重置错误码

2. 使用示例


版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词