select和poll实现及驱动支持

本文详细介绍了Linux系统中select和poll的实现机制,从应用层接口到内核中的具体实现,再到驱动如何支持这两种机制。讨论了select的参数、返回值以及在内核中的操作,对比了poll的特性,并分析了驱动如何判断文件状态并唤醒等待的进程。
摘要由CSDN通过智能技术生成

select和poll实现及驱动支持


1. 应用层接口

1.1 select

原型:

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

参数:
nfds 是readfds、writefds、exceptfds中登记的文件描述符的最大值再加 1。
readfds 是监控文件非阻塞可读的描述符集合,也可以监控文件是否读到末尾(file descriptor is also ready on end-of-file)。
writefds 是监控文件非阻塞可写的描述符集合。
exceptfds 是监控文件异常的描述符集合。
timeout select超时时间,如果timeout里的值为0,则立即返回, 如果该参数为NULL,则一直阻塞直到事件出现,如果设置了超时时间,但是在超时之前有事件发生,select返回,那么timeout里的值是剩余的时间。

文件描述符集合可用宏操作:

void FD_SET(int fd, fd_set *set)    将fd设置到set集合中
void FD_CLR(int fd, fd_set *set)    将fd从集合set中清除
void FD_ZERO(fd_set *set)           清空set集合
int FD_ISSET(int fd, fd_set *set)   测试set集合中fd是否被设置来判断是否可读、可写、出现异常

返回值:
当成功时,select返回readfds, writefds, exceptfds三个集合中文件可操作的文件描述符的总数,也就是三个集合中所有位的设置总数。例如readfds和writefds中设置了同一个文件,当该文件同时可读可写时select返回,那么返回值就是2。
当错误时返回负数值,根据具体返回值进行处理。
当返回值是0时,表示超时。

1.2 poll

原型:

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

参数:
fds 是一个结构体数组,结构体如下:

struct pollfd{
  int fd;              //监控的文件描述符
  short events;        //监控的事件,用下面的标志位标志,不能设置成最后三个错误标志位
  short revents;       //返回的事件,用下面的标志位标志,如果没有事件发生,这个成员会被清空
};
POLLIN     普通或优先级带数据可读
POLLRDNORM 普通数据可读
POLLRDBAND 优先级带数据可读
POLLPRI    高优先级数据可读

POLLOUT    普通或优先级带数据可写
POLLWRNORM 普通数据可写
POLLWRBAND 优先级带数据可写

POLLERR    发生错误
POLLHUP    发生挂起
POLLVAL    描述字不是一个打开的文件

nfds 是第一个元素的个数
timeout 超时时间,单位是毫秒,当设置成0,立即返回,设置成-1,会一直阻塞直到有事件发生

返回值:
成功返回正整数,表示所有事件的数量,包括正常的可读写事件和错误事件;
超时返回0;
出错返回-1,检查errno得到错误原因。


2. 内核中实现

2.1 select

select在内核中的入口在fs/select.c中:

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 = 
epoll是一个在Linux内核中提供的I/O事件通知机制,采用了事件驱动的方式,用于高效处理大量的并发连接。它与selectpoll相比有以下区别: 1. 底层实现:epoll在内核中使用红黑树(红黑树是一种自平衡的二叉搜索树)来存储和管理文件描述符,以及相应的事件。而selectpoll则是通过遍历一个事件集合进行查询。 2. 打开的文件描述符数量限制:selectpoll都将所有的文件描述符拷贝到内核空间中,因此有一个最大限制值(FD_SETSIZE),默认为1024(可以通过修改宏定义来改变)。而epoll没有这个限制,它采用事件驱动的方式,在注册的文件描述符上有事件发生进行通知,因此没有限制。 3. 效率:由于epoll采用事件驱动的方式,只有在有事件发生进行通知,因此能够大大提高效率,减少了遍历文件描述符的开销。而selectpoll则在调用需要遍历整个事件集合,效率较低。 4. 内存拷贝:selectpoll在每次调用都需要将所有监视的文件描述符集合拷贝到内核中,而epoll只需要在开始注册,并且不需要拷贝。 5. 高并发支持:由于epoll采用事件驱动的方式,能够更好地处理大量并发连接。而selectpoll则在大量文件描述符会有性能下降的问题。 综上所述,epoll可以更高效地处理大量并发连接,并且没有文件描述符数量限制,相比之下selectpoll的性能较低,且有文件描述符数量限制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值