poll机制

Select系统调用用于多路监控,当没有一个文件满足要求时,select将阻塞调用进程
int select(int maxfd, fd_set *readfds, fd_set *writefds, fe_set*exceptfds, const struct timeval *timeout)
——————/
Maxfd:文件描述符范围,比待检测文件描述符最大值大1
Readfds:读监控文件描述符集
Writefds:写监控文件描述符集
Exceptfds:异常监控文件描述符集
Timeout值为0,不管是否有文件满足要求,都立刻返回,无文件满足要求返回0,有文件满足要求返回一正值
Timeout为NULL,select将阻塞进程,直到某文件满足要求
Timeout值为正整数(所指向结构体其某成员值),即超时时间
——————/
Select调用返回值情况:
正常情况返回满足要求文件描述符个数
经过timeout等待后仍无文件满足要求,返回0
如select被某信号中断,返回-1并设置errno为EINTR
如出错,返回-1并设置相应errno
——————/
Select系统调用使用方法:
1. 将要监控文件添加到文件描述符集
2. 调用Select监控
3. 判断文件是否发生变化
——————/
系统提供4个宏对描述符集进行操作:
#include <sys/select.h>
void FD_SET(int fd, fd_set *fdset)
void FD_CLR(int fd, fd_set *fdset)
void FD_ZERO(fd_set *fdset)
void FD_ISSET(int fd, fd_set *fdset)
宏FD_SET将文件描述符fd添加到文件描述符集fdset中;
宏FD_CLR从文件描述符集fdset中清除文件描述符fd;
宏FD_ZERO清空文件描述符集fdset;
在调用select后使用FD_ISSET来检测文件描述符集fdset中的文件fd是否发生了变化
——————/
FD_ZERO(&fds); //清空集合
FD_SET(fd1,&fds); //设置描述符
FD_SET(fd2,&fds); //设置描述符
maxfdp=fd1+1; //描述符最大值加1,假设fd1>fd2
switch(select(maxfdp,&fds,NULL,NULL,&timeout))
	case -1: 
		exit(-1);	//select错误,退出程序
	case 0:
		break;
	default:
		if(FD_ISSET(fd1,&fds)) //测试fd1是否可读
——————/
select系统调用可能会阻塞进程,该调用由驱动poll方法实现,原型:
unsigned int (*poll)(struct file *filp,poll_table *wait)
void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
——————/
1. 使用poll_wait将等待队列添加到poll_table中
2. 返回描述设备是否可读或可写的掩码
——————/位掩码
POLLIN设备可读
POLLRDNORM数据可读
POLLOUT设备可写
POLLWRNORM数据可写
设备可读通常返回(POLLIN|POLLRDNORM )
设备可写通常返回(POLLOUT|POLLWRNORM )
——————/
static unsigned int mem_poll(struct file *filp,poll_table *wait)
{
	struct scull_pipe *dev =filp->private_data;
	unsigned int mask =0;
	poll_wait(filp,&dev->inq,wait);
	if (可读)
		mask = POLLIN |POLLRDNORM;/*设备可读,返回掩码*/
	return mask;
}
Poll方法仅做一登记,真正阻塞发生在select.c的do_select函数
——————/
Select    //app
do_select    //kernel
	for(;;) {
		for (j = 0; j < __NFDBITS; ++j, ++i, bit <<= 1)	//因监控多个文件
			struct file *file= fget_light(i, &fput_needed);
			struct file_operations *f_op= file->f_op;
			mask = (*f_op->poll)(file, wait);
			//	#define POLLIN_SET (POLLRDNORM | POLLIN |……)
			if ((mask & POLLIN_SET) && (in & bit))	
			// (in & bit)判断file可读否,但poll返回可写,不应将retval++
				retval++;    //初始值0
		if (retval || timed_out || signal_pending(current))
			break;	//跳出最外层循环不阻塞,否则执行下句带超时可唤醒调度
		poll_schedule_timeout(&table, TASK_INTERRUPTIBLE,to, slack))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值