目录
知识补给站
对文件描述符集合操作的四个宏操作
对文件描述符集合操作的四个宏操作在select
函数中起着关键的作用,它们用于初始化、添加、删除和检查文件描述符集合中的元素。这四个宏为: FD_ZERO、FD_SET、FD_CLR、FD_ISSET:
FD_ZERO(fd_set *fdset)
-
功能:清空文件描述符集合。
-
参数:一个指向
fd_set
类型变量的指针。 -
作用:将
fdset
指向的文件描述符集合中的所有位都设置为0,确保集合中没有包含任何文件描述符。
FD_SET(int fd, fd_set *fdset)
- 功能:将一个文件描述符添加到文件描述符集合中。
- 参数:一个整数
fd
,代表要添加的文件描述符;一个指向fd_set
类型变量的指针。 - 作用:将
fdset
指向的文件描述符集合中对应于fd
的位设置为1,表示该集合包含文件描述符fd
。
FD_CLR(int fd, fd_set *fdset)
- 功能:从文件描述符集合中删除一个文件描述符。
- 参数:一个整数
fd
,代表要删除的文件描述符;一个指向fd_set
类型变量的指针。 - 作用:将
fdset
指向的文件描述符集合中对应于fd
的位设置为0,表示该集合不再包含文件描述符fd
。
FD_ISSET(int fd, fd_set *fdset)
- 功能:检查文件描述符集合中是否包含某个文件描述符。
- 参数:一个整数
fd
,代表要检查的文件描述符;一个指向fd_set
类型变量的指针。 - 返回值:如果
fdset
指向的文件描述符集合中包含fd
,则返回非零值(通常为1);否则返回0。 - 作用:用于在
select
函数返回后,检查哪些文件描述符已经就绪(可读、可写或存在异常条件)。
服务器IO多路复用中的select和poll的区别
- 数据结构差异:
(1)select:使用位图(bitmap)数据结构来存储被监听的文件描述符集合。这种数据结构在文件描述符数量较少时效率较高,但受限于位图的大小,通常能监听的文件描述符数量有限(通常在1024个左右,取决于系统和库的实现)。
(2)poll:使用结构体数组(如pollfd)来存储被监听的文件描述符及其相关事件。这种数据结构允许监听更多的文件描述符,因为它不受位图大小的限制。 - 事件绑定:
(1)select:没有将文件描述符和事件进行绑定。每次调用select时,都需要通过三个独立的文件描述符集合来指定要监听的可读、可写和异常事件。
(2)poll:将文件描述符和事件直接绑定在pollfd结构体中,这使得编程接口更为简洁。在调用poll时,只需传递一个包含所有监听信息的pollfd数组即可。 - 数据拷贝:
(1)select:在每次调用时,都需要将文件描述符集合从用户空间拷贝到内核空间,并在返回时将结果从内核空间拷贝回用户空间。这种频繁的数据拷贝在文件描述符数量较多时会导致性能下降。
(2)poll:同样存在数据拷贝的问题,但由于poll使用结构体数组而不是位图,因此在某些情况下可能具有更高的效率。 - 时间复杂度:
(1)select:在内核中无差别地遍历每个文件描述符,时间复杂度为O(n)。当文件描述符数量较大时,性能会受到显著影响。
(2)poll:与select类似,也需要在内核中遍历每个文件描述符。但由于poll允许监听更多的文件描述符,因此在某些情况下可能具有更好的性能。 - 可重用性:
(1)select:每次调用select时,都需要重新创建和设置文件描述符集合。这可能导致额外的编程开销。
(2)poll:由于poll将文件描述符和事件绑定在结构体中,因此可以在多次调用之间重用相同的pollfd数组,从而减少了编程开销。