套接字之select系统调用
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系统调用的更多相关文章
- 套接字之recv系统调用
recv系统调用对sys_recvfrom进行了简单的封装,只是其中不包含地址信息,其只需要从建立连接的另一端接收信息: /* * Receive a datagram from a socket. ...
- 套接字之send系统调用
send系统调用只是对sendto系统调用进行了封装,传递的参数不包含目的地址信息,数据会发送到已经建立连接的另一端的地址: /* * Send a datagram down a socket. * ...
- 套接字之close系统调用
close系统调用用于关闭文件描述符,其系统调用实现如下所示: / * Careful here! We test whether the file pointer is NULL before * ...
- python 套接字之select poll epoll
python下的select模块使用 以及epoll与select.poll的区别 先说epoll与select.poll的区别(总结) select, poll, epoll 都是I/O多路复用的具 ...
- Linux 套接字编程 - select
select 可以感知文件表述符集合中的变化,如果办fd0(即标准输入)放入select的read fd set,发现只有按回车的时候select才会返回.查了下要把终端的缓冲大小设为1,这样就能实现 ...
- 套接字之recvmsg系统调用
recvmsg系统调用允许用户指定msghdr结构来接收数据,可以将数据接收到多个缓冲区中,并且可以接收控制信息:接收信息过程与其他接收系统调用核心一致,都是调用传输层的接收函数进行数据接收: SYS ...
- 套接字之recvfrom系统调用
recvfrom系统调用通过用户传入的接收空间构造msghdr,并且调用sock_recvmsg,该函数调用socket操作的recvmsg函数sock->ops->recvmsg,ipv ...
- 套接字之sendmsg系统调用
sendmsg系统调用允许在用户空间构造消息头和控制信息,用此函数可以发送多个数据缓冲区的数据,并支持控制信息:当调用进入内核后,会将用户端的user_msghdr对应拷贝到内核的msghdr中,然后 ...
- 套接字之sendto系统调用
sendto系统调用用于向指定的目的地址发送数据,其系统调用的流程比较容易理解,如下面所示,其主要完成 (1)将用户数据组织成msghdr,(2)而后调用socket操作的sendmsg:ipv4对应 ...
随机推荐
- java虚拟机精讲
2.程序计数器 是指当前线程所执行字节码的行号指示器 比如if 循环 抛异常 等都需要程序计数器 如果线程执行java方法 程序计数器记录的是虚拟机字节码指令的地址 如果线程执行native方法时程序 ...
- POI操作OFFICE转HTML
由于项目需求,需要上传在线预览生成的office文件,经过一番痛苦的研究,目前已经成功将DOC.DOCX.PPTX不乱码转换成功,PPT当字体不是宋体时出现乱码,至今无法解决,待日后再研究吧.而EXC ...
- 在web项目中配置log4j
在web.xml中添加如下代码 <context-param> <param-name>contextConfigLocation</param-name> < ...
- C++参数传递与STL
C++参数传递与STL 这是一篇备忘录形式的内容,涉及到的内容比较基础 今天写了一个小算法,用一个set在函数间传递,记录各个函数中的结果.但是最后结果显示set中的元素是0个.查了一下才发现,用来C ...
- Nginx默认配置语法
Nginx默认配置语法 1. 我们进入 /etc/nginx/目录下,打开 nginx.conf文件 2. 我们来解析下 这里面标签和各模块的作用 # 设置nginx服务的系统使用用户 user ...
- nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'enterpriseId' in 'class java.lang.String'
错误信息: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for p ...
- springboot-异步线程调用
启动类:添加@EnableAsync注解 @SpringBootApplication @EnableAsync public class Application{ public static voi ...
- dedecms 调用内容页分页
arc.archives.class.php $TRUEfilename = $this->GetTruePath().$fileFirst."_".$i.".&q ...
- 5.(基础)tornado异步
终于到了传说中的异步了,感觉异步这个名字听起来就很酷酷的,以前还不是多擅长Python时,就跑去看twisted的源码,结果给我幼小的心灵留下了创伤.反正包括我在内,都知道异步编程很强大,但是却很少在 ...
- 一般情况下的NB-IoT网络架构
一. NB总体网络架构 NB-IoT端到端系统架构如下图所示: 终端:UE(User Equipment),通过空口连接到基站(eNodeB(evolved Node B , E-UTRAN 基站)) ...