多路复用的底层实现

这里先介绍一下select函数:

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
/*	功能:监听多个描述符,阻塞等待有一个或者多个文件描述符,准备就绪。
		内核将没有准备就绪的文件描述符,从集合中清掉了。
	参数:  nfds			最大文件描述符数 ,加1
			readfds		读文件描述符集合
			writefds		写文件描述符集合
			exceptfds		其他异常的文件描述符集合
			timeout		超时时间(NULL)
	返回值:当timeout为NULL时返回0,成功:准备好的文件描述的个数  出错:-1 
		   当timeout不为NULL时,如超时设置为0,则select为非阻塞,超时设置 > 0,则无描述符可被操作的情况下阻塞指定长度的时间 
*/

那select函数怎么知道所监测的文件描述符可读或则可写了呢?

以下是select函数的底层驱动代码实现:

unsigned int mychar_poll(struct file *pfile,poll_table *wait)
{

	struct my_cedv * my_dev=(struct my_cedv*)pfile->private_data;
	unsigned int mask=0;
	poll_wait(pfile,&my_dev->rd,wait);

	poll_wait(pfile,&my_dev->we,wait);
	if(my_dev->curlen>0)
	{
		mask|=POLLIN |POLLRDNORM;

	}
	if(N-my_dev->curlen>0)
	{
		mask |=POLLOUT | POLLWRNORM;
	}
	return mask;



	
}
  1. poll_wait函数可以被 select/poll/epoll 等系统调用使用:poll_wait 函数通常被用于为实现基于事件驱动 I/O 复用的系统调用提供支持,比如 selectpollepoll 等。当文件描述符上发生了对应的事件时(根据返回值mask),poll_wait 函数可以唤醒在该文件描述符上等待的进程(并且将对应的读文件描述符集合中对应的位置一),从而实现了对文件描述符事件状态的监听和通知。(当没有事件时就会休眠,放入等待队列中

  2. 当第一个if条件成立时,即有可读事件就会给mask赋值。当第二个if条件成立时,即有可写事件成立就会给mask赋值。

  3. 内核会根据mask值和poll_wait 函数,将相应的进程唤醒。

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值