Amu*_*umu 2 c bit-manipulation
根据这篇文章民意调查 vs 选择 vs 基于事件:
select() 每个文件描述符仅使用(最多)3 位数据,而 poll() 通常每个文件描述符使用 64 位数据。因此,在每个系统调用中调用 poll() 都需要将更多内容复制到内核空间。select() 的一个小胜利。
这是fd_set的实现(在Advisories上找到:多个应用程序fd_set结构位图数组索引溢出
#ifndef FD_SETSIZE
#define FD_SETSIZE 1024
#endif
#define NBBY 8 /* number of bits in a byte */
typedef long fd_mask;
#define NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
#define howmany(x,y) (((x)+((y)-1))/(y))
typedef struct _types_fd_set {
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
} _types_fd_set;
#define fd_set _types_fd_set
Run Code Online (Sandbox Code Playgroud)
所以,最终,fd_set只是一个long. 书中还写道:
对 FD_SET 的调用使用套接字号作为索引将一位设置为 1:
这意味着,如果我得到一个套接字 fd 编号为 5,则索引为 5 的元素将被选择,并且其第一位将从 0 翻转到 1。由于select()使用 3 位,我猜其他两位用于发送和接收。它是否正确?为什么要select()使用 long,而它只需要 3 位?
另外,如上所述,poll()使用 64 位进行检查。为什么poll需要检查pollfd结构体中的每一位?这是pollfd结构:
struct pollfd {
int fd; // the socket descriptor
short events; // bitmap of events we're interested in
short revents; // when poll() returns, bitmap of events that occurred
};
Run Code Online (Sandbox Code Playgroud)
该结构体中的总位为 64 位,其中一个 32 位 int 和两个 16 位 Short。我知道检查位标志的常用方法是使用AND (&)运算符过滤掉其他不相关的位。这适用于本案吗?
poll() 通常每个文件描述符使用 64 位。因此,在每个系统调用中调用 poll() 都需要将更多内容复制到内核空间。select() 的一个小胜利。
谬论——如果你只想监视一个 fd,poll(2) 会让你摆脱这 64 位,而对于 select(),你必须复制最多 12288 位(3 组,通常每组 4096 位)。
另外,poll() 支持大于 FD_SETSIZE 值的fd 。