poll和epoll内核原码刨析(1)

目录

一、poll函数介绍

二、poll原码的刨析


一、poll函数介绍

        poll 函数是 Linux 系统中用于实现 I/O 多路复用的函数,可用来监控多个文件描述符,检查它们的状态是否发生变化,如是否可读、可写或产生错误等,常用于同时处理多个网络连接或文件操作的场景。

int poll(struct pollfd*fds,nfds_t nfds,int timeout);
/*
fds:指向struct pollfd结构类型的数组指针,每个数组元素指定一个被监视的文件描述符及其相关事件
    struct pollfd{
	    int fd;//文件描述符
        short events;//等待的需要测试事件,由用户设置
        short revents;//实际发生了的事件,由内核在函数返回时设置
    };
nfds:nfds_t类型,用于标记fds数组中的结构体元素的总数量
timeout:指定poll函数调用的阻塞时间,单位为毫秒
        -1:一直阻塞,直到所检测的文件描述符上感兴趣的事件发生,或捕获到信号
        0:立即返回,不阻塞线程
        >0:等待指定的毫秒数,如果在这段时间内没有感兴趣的事件发生,函数超时返回
*/

二、poll原码的刨析

        poll系统调用的原理:先注册回调函数__poll_wait,再初始化table变量,接着拷贝用户传入的struct pollfd(主要是fd),然后轮流调用所用的fd对应的poll(把current挂在各个fd对应的设备等待队列上)

1.分析table

        在第19行定义了一个poll_queue_proc的函数指针类型;在第21-23行,结构体成员qproc是一个函数指针类型,即struct poll_table结构体包含了一个函数指针

2.分析poll_initwait

        poll_initwait把table变量的成员poll_table对应的回调函数设置为__pollwait

        __pollwait是操作系统的异步操作的“御用”回调函数,但是epoll并不使用此,它另增了一个回调函数,达到高速运转

3.分析sys_poll

        此代码中链表节点由一个指向struct poll_list的指针控制,而众多的struct pollfd就通过struct_list的entires成员访问。循环就是把用户态的struct pollfd拷进这些entries

        当用户传入的fd很多时,由于poll系统调用每次都要把所有struct pollfd拷进内核,所以参数传递和页分配此时就成了poll系统调用的性能瓶颈(问题一)

4.分析do_poll

         注意438行的set_current_state和445行的signal_pending,它们两句保障了当用户程序在调用poll后挂起时,发信号可以让程序迅速推出poll调用,而通常的系统调用是不会被信号打断的

        440-443行,当用户传入的fd很多时,对do_pollfd就会调用很多次(问题二)

        do_pollfd就是针对每个传进来的fd,调用他们各自对应的poll函数(do_pollfd调用的是网络设备驱动实现的poll)

5.驱动程序

        设备驱动程序的标准实现:调用poll_wait,即以设备自己的等待队列为参数,调用struct poll_table的回调函数

6.分析__poll_wait

        __poll_wait的作用就是创建所示的数据结构,并通过struct poll_table_entry的wait成员,把current挂在了设备的等待队列上,此处的等待队列是wait_address

内容参考文章:http://donghao.org/uii/

后续文章对epoll进行刨析...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值