1.IO multiplexing、select 、core_sys_select

1. 什么是IO multiplexing?

IO multiplexing是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。在Linux系统中,常用的IO multiplexing手段有 select、poll 和 epoll。

IO multiplexing 主要用于处理网络请求,例如可以把多个请求句柄添加到 select 中进行监听,当有请求可进行IO的时候就会告知进程,并且把就绪的请求句柄保存下来,进程只需要对这些就绪的请求进行IO操作即可。下面通过一幅图来展示 select 的使用方式

2.IO multiplexing的基本原理

进程中阻塞select的系统调用,而不是阻塞I/O调用。
阻塞select系统调用等待socket可读,当select返回该socket可读时,用户进程激活,便调用recvfrom将数据报复制到的应用程序缓区中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TNKVK2j5-1608088631639)(https://notes.shichao.io/unp/figure_6.3.png)]

3.Select process执行流


3.1 sys_selcet

下面为sys_select系统调用的代码

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 there is a timeout value*/
		if (copy_from_user(&tv, tvp, sizeof(tv))) 
			return -EFAULT;

		to = &end_time;
		/* set timeout, if Invalid time,then return -EINVAL*/
		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;
}

3.2 core_sys_select

该函数的主要作用是将用户空间的参数拷贝到内核,及将系统调用的返回值拷贝到用户空间

int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
			   fd_set __user *exp, struct timespec *end_time)
{
	fd_set_bits fds;
	
    /*
      计算max_fds,依据它使用kmalloc为fd_set_bits类型的变量分配内存:bits,该变量存储readfds、writefds、exceptfds共计6个集合        
    */
    ......(Part omitted)
    
    / *  get_fd_set just calls copy_from_user to copy FD_SET from user space * /
	if ((ret = get_fd_set(n, inp, fds.in)) ||
	    (ret = get_fd_set(n, outp, fds.out)) ||
	    (ret = get_fd_set(n, exp, fds.ex)))
		goto out;
	zero_fd_set(n, fds.res_in);  //clear
	zero_fd_set(n, fds.res_out);
	zero_fd_set(n, fds.res_ex);

	ret = do_select(n, &fds, end_time);

	if (ret < 0)  // nagetive,error
		goto out;
	if (!ret) {
		ret = -ERESTARTNOHAND;
		if (signal_pending(current)) // 检测到有信号则系统调用退出,返回用户空间执行信号处理函数
			goto out;
		ret = 0;
	}
    / *Copy the result set back to user space* / 
	if (set_fd_set(n, inp, fds.res_in) ||
	    set_fd_set(n, outp, fds.res_out) ||
	    set_fd_set(n, exp, fds.res_ex))
		ret = -EFAULT;

out:
	if (bits != stack_fds)
		kfree(bits);      /* corresponding to kmalloc above */ 
out_nofds:
	return ret;
}


参考

Select system call source code analysis
Chapter 6. I/O Multiplexing: The select and poll Functions

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值