select是IO多路复用的一种方式,用来等待一个列表中的多个描述符的可读可写状态;

 SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp,
fd_set __user *, exp, struct timeval __user *, tvp)
{
struct timespec64 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, , ret); return ret;
}

本文主要分析socket的select操作,所以对于select系统调用前面通用的部分,我们只分析其调用关系,如下,可见在do_select函数中,会调用文件操作的poll函数;

  /**
* select系统调用函数调用关系
* sys_select
* |-->core_sys_select
* |-->do_select
* |-->f_op->poll 调用文件的poll操作
*/

socket文件操作结构实现如下,我们本文重点分析poll操作,即sock_poll函数;

 /*
* Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
* in the operation structures but are done directly via the socketcall() multiplexor.
*/
/* socket文件操作函数 */
static const struct file_operations socket_file_ops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read_iter = sock_read_iter,
.write_iter = sock_write_iter,
.poll = sock_poll,
.unlocked_ioctl = sock_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = compat_sock_ioctl,
#endif
.mmap = sock_mmap,
.release = sock_close,
.fasync = sock_fasync,
.sendpage = sock_sendpage,
.splice_write = generic_splice_sendpage,
.splice_read = sock_splice_read,
};

sock_poll函数在获取到socket之后,会调用其操作中的poll函数,其中tcp为tcp_poll,udp为udp_poll;

 /* No kernel lock held - perfect */
static unsigned int sock_poll(struct file *file, poll_table *wait)
{
unsigned int busy_flag = ;
struct socket *sock; /*
* We can't return errors to poll, so it's either yes or no.
*/
/* 获取到socket */
sock = file->private_data; if (sk_can_busy_loop(sock->sk)) {
/* this socket can poll_ll so tell the system call */
busy_flag = POLL_BUSY_LOOP; /* once, only if requested by syscall */
if (wait && (wait->_key & POLL_BUSY_LOOP))
sk_busy_loop(sock->sk, );
} /* 执行socket操作中的poll,tcp为tcp_poll,udp为udp_poll */
return busy_flag | sock->ops->poll(file, sock, wait);
}

tcp_poll的代码分析会在阅读tcp源码时补充;

套接字之select系统调用的更多相关文章

  1. 套接字之recv系统调用

    recv系统调用对sys_recvfrom进行了简单的封装,只是其中不包含地址信息,其只需要从建立连接的另一端接收信息: /* * Receive a datagram from a socket. ...

  2. 套接字之send系统调用

    send系统调用只是对sendto系统调用进行了封装,传递的参数不包含目的地址信息,数据会发送到已经建立连接的另一端的地址: /* * Send a datagram down a socket. * ...

  3. 套接字之close系统调用

    close系统调用用于关闭文件描述符,其系统调用实现如下所示: / * Careful here! We test whether the file pointer is NULL before * ...

  4. python 套接字之select poll epoll

    python下的select模块使用 以及epoll与select.poll的区别 先说epoll与select.poll的区别(总结) select, poll, epoll 都是I/O多路复用的具 ...

  5. Linux 套接字编程 - select

    select 可以感知文件表述符集合中的变化,如果办fd0(即标准输入)放入select的read fd set,发现只有按回车的时候select才会返回.查了下要把终端的缓冲大小设为1,这样就能实现 ...

  6. 套接字之recvmsg系统调用

    recvmsg系统调用允许用户指定msghdr结构来接收数据,可以将数据接收到多个缓冲区中,并且可以接收控制信息:接收信息过程与其他接收系统调用核心一致,都是调用传输层的接收函数进行数据接收: SYS ...

  7. 套接字之recvfrom系统调用

    recvfrom系统调用通过用户传入的接收空间构造msghdr,并且调用sock_recvmsg,该函数调用socket操作的recvmsg函数sock->ops->recvmsg,ipv ...

  8. 套接字之sendmsg系统调用

    sendmsg系统调用允许在用户空间构造消息头和控制信息,用此函数可以发送多个数据缓冲区的数据,并支持控制信息:当调用进入内核后,会将用户端的user_msghdr对应拷贝到内核的msghdr中,然后 ...

  9. 套接字之sendto系统调用

    sendto系统调用用于向指定的目的地址发送数据,其系统调用的流程比较容易理解,如下面所示,其主要完成 (1)将用户数据组织成msghdr,(2)而后调用socket操作的sendmsg:ipv4对应 ...

随机推荐

  1. python:set() 函数

    描述 Python 内置函数 创建一个无序不重复元素集 可进行关系测试,删除重复数据 集合对象还支持union(联合), intersection(交), difference(差)和sysmmetr ...

  2. Python基础教程之dict和set

    1. dict Python中的dict等于js中的 map ,使用键-值(key-value)存储,具有极快的查找速度. 如果 我们要根据同学的姓名去查找他的成绩在不用dict的情况下.就需要两个l ...

  3. IDEA打开光标是粗黑色,backspace键、insert键点击无效的解决办法

    问题描述:打开IDEA的编译器之后,界面显示的光标变粗,点击backspace键和insert键盘之后无效 解决方法:打开File——Settings——Plugins,在右侧的搜索栏中搜索IdeaV ...

  4. 格式化json扩展

    json-handle 直接在chrome应用商店搜索JSON-handle或者去github搜索可用插件即可

  5. SpringBoot 在IDEA中实现热部署(实用版)(引入)

    SpringBoot 在IDEA中实现热部署(实用版) 引用:https://www.jianshu.com/p/f658fed35786 好的热部署让开发调试事半功倍,这样的“神技能”怎么能错过呢, ...

  6. Centos7基础优化操作项

    1.基础优化操作项:更新yum源信息第一个:就近使用yum源地址,安装软件更快.curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors. ...

  7. mysql5.7.26 基于GTID的主从复制环境搭建

    简单工作原理: (1)从库执行 change master to 语句,会立即将主库信息记录到master.info中 (2)从库执行 start slave语句,会立即生成IO_T和SQL_T (3 ...

  8. HDU - 6589 Sequence (生成函数+NTT)

    题目链接 设序列a的生成函数$\large f(x)=\sum\limits_{i=0}^{n-1}a_ix^i$,则操作1,2,3分别对应将$f(x)$乘上$\Large\frac{1}{1-x}, ...

  9. 优秀.NET界面控件DevExpress v19.1.6全新来袭!新改进抢“鲜”看

    DevExpress Universal Subscription(又名DevExpress宇宙版或DXperience Universal Suite)是全球使用广泛的.NET用户界面控件套包,De ...

  10. 通过实现接口runnable实现多线程

    实现Runnable接口实现多线程的步骤(1)编写类实现Runnable接口(2)实现run(方法(3)通过Thread类的start(方法启动线程 静态代理模式Thread >代理 角色MyR ...