select 系统调用用于多路监控,当没有一个文件满足要求时,select 将阻塞调用进程。
int select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set
*exceptfds, const struct timeval *timeout)
maxfd:文件描述符的范围,比待检测的最大文件描述符大 1
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
timeout 值为 0,不管是否有文件满足要求,都立刻返回,无文件满足要求返回 0,有文件满足要求返回一个正值。
timeout 值为 NULL,select 将阻塞进程,直到某个文件满足要求。
timeout 值为正整数,就是等待的最长时间,即 select 在 timeout 时间内阻塞进程。
与 select 系统调用对应的 poll 设备方法如下:
unsigned int (*poll) (struct file *file, poll_table *wait);
typedef struct poll_table_struct {
poll_queue_proc qproc;
} poll_table;
1.使用 poll_wait 将等待队列添加到 poll_table 中。
void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
{
if (p && wait_address)
p->qproc(filp, wait_address, p);
}
2.返回描述设备是否可读或可写的掩码。
if(有数据可读) //根据具体的驱动实现
mask = POLLIN | POLLRDNORM;
return mask;
位掩码:
POLLIN 设备可读
POLLRDNORM 数据可读
POLLOUT 设备可写
POLLWRNORM 数据可写
设备可读通常返回 (POLLIN | POLLRDNORM)
设备可写通常返回 (POLLOUT | POLLWRNORM)
do_select
poll_initwait(&table);
init_poll_funcptr(&pwq->pt, __pollwait);
for (;;) {
for (j = 0; j < __NFDBITS; ++j, ++i, bit <<= 1) {
if (f_op && f_op->poll)
mask = (*f_op->poll)(file, retval ? NULL : wait);
}
/* 返回的条件是 1.有文件可读或可写 2.超时 3.有信号 */
if (retval || timed_out || signal_pending(current))
break;
poll_schedule_timeout //阻塞发生在select系统调用的实现中
}
与 select 系统调用类似,poll 系统调用同样可以完成上述功能。
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
struct pollfd {
int fd; /* file descriptor */
short events; /* request events */
short revents; /* returned events */
};
nfds:要监控的文件数量
timeout:超时时间,以 ms 为单位
select 用户空间编程示例:
FD_ZERO(&fds); //清空集合
FD_SET(fd1, &fds); //设置描述符
FD_SET(fd2, &fds);
maxfd = fd1 + 1;
switch(select(maxfd, &fds, NULL, NULL, &timeout))
{//判断返回值
case xxx: if(FD_ISSET(fd1,&fds))
……
}
……
系统提供了几个宏对描述符集进行操作:
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)
poll 用户空间编程示例:
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN;
ret = poll(fds, 1, 5000);
……
——忠于梦想 勇于实践 linux_xpj@opencores.org
阅读(1309) | 评论(0) | 转发(0) |