select函数源码简析

本文简要分析了Linux内核中的select函数,详细介绍了从用户态到内核态的转换过程,以及select如何处理文件描述符的就绪状态。核心操作在core_sys_select()函数中,包括分配存储空间、遍历文件描述符等。select函数的效率随着文件描述符数量的增加而降低,因为它需要逐一检查每个描述符的就绪状态。
摘要由CSDN通过智能技术生成

1 简介

select()允许一个程序监听多个文件描述符,等待一个或者多个文件描述符的I/O操作变成“就绪”状态(比如:可读)。

/* According to POSIX.1-2001 */
#include <sys/select.h>

/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int select(int nfds, fd_set *readfds, fd_set *writefds,
          fd_set *exceptfds, struct timeval *timeout);

void FD_CLR(int fd, fd_set *set);
int  FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);

#include <sys/select.h>

int pselect(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, const struct timespec *timeout,
           const sigset_t *sigmask);

int nfds参数表示待监听的集合里的最大文件描述符的值 + 1。

fd_set *readfdsfd_set *writefdsfd_set *exceptfds三个集合分别存放需要监听读、写、异常三个操作的文件描述符。

struct timeval *timeout表示超时时间。设为0则立刻扫描并返回,设为NULL则永远等待,直到有文件描述符就绪。

2 SYSCALL_DEFINE5(select, …

阅读的Linux内核版本:linux-2.6.32.68

select源码位于fs/select.c文件

SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,
        fd_set __user *, exp, struct timeval __user *, tvp)
{
    struct timespec end_time, *to = NULL;
    struct timeval tv;
    int ret;

    if (tvp) {
        if (copy_from_user(&tv, tvp, sizeof(tv)))
            return -EFAULT;

        to = &end_time;
        if (poll_select_set_timeout(to,
                tv.tv_sec + (tv.tv_usec / USEC_PER_SEC),
                (tv.tv_usec % USEC_PER_SEC) * NSEC_PER_USEC))   //微秒转纳秒
            return -EINVAL;
    }

    ret = core_sys_select(n, inp, outp, exp, to);
    ret = poll_select_copy_remaining(&end_time, tvp, 1, ret);

    return ret;
}

select函数执行从此开始,关键调用流程如下: select -> core_sys_select() -> do_select() 。

selcet的主要操作在do_select()函数中完成。

在上述函数中,主要把超时时间tvp的值从用户空间复制到内核空间,并且调用poll_select_set_timeout()函数把超时时间的长度加到当前时间上,获得最终的结束时间点to。由于poll_select_set_timeout()的时间精度是纳秒,所以需要转换。

之后调用core_sys_select()函数执行主要逻辑。

在主要程序执行完之后,还会调用poll_select_copy_remaining()把等待时间中的剩余时间返回给用户态的tvp

3 core_sys_select()

/*
 * We can ac
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值