在一个只读 fd 上进行 IO 多路复用是否有助于获得比简单地阻塞读取更好的性能?

Does IO multiplexing on one single read-only fd help get better performance than simply blocking read on it?

据我所知,我认为如果我只需要对单个fd执行读取操作,像select/poll这样的IO多路复用对性能没有帮助,它甚至比只阻塞地读取fd造成更多的开销。

但是linux auditd project却在一个单一的读数插座上使用select。有人可以解释一下它的含义吗?

auditd 代码还在 1 个套接字/1 个管道和 5 个信号上使用了 libev。如果我只关心主 netlink 套接字,使用阻塞读取是否更好?

我认为可能的场景可能是监听 udp 接收器套接字等

为方便起见附上代码块。提前致谢!

925 static int get_reply(int fd, struct audit_reply *rep, int seq)
926 {
927         int rc, i;
928         int timeout = 30; /* tenths of seconds */
929 
930         for (i = 0; i < timeout; i++) {
931                 struct timeval t;
932                 fd_set read_mask;
933 
934                 t.tv_sec  = 0;
935                 t.tv_usec = 100000; /* .1 second */
936                 FD_ZERO(&read_mask);
937                 FD_SET(fd, &read_mask);
938                 do {
939                         rc = select(fd+1, &read_mask, NULL, NULL, &t);
940                 } while (rc < 0 && errno == EINTR);
941                 rc = audit_get_reply(fd, rep, 
942                         GET_REPLY_NONBLOCKING, 0);
943                 if (rc > 0) {
944                         /* Don't make decisions based on wrong packet */
945                         if (rep->nlh->nlmsg_seq != seq)
946                                 continue;
947 
948                         /* If its not what we are expecting, keep looping */
949                         if (rep->type == AUDIT_SIGNAL_INFO)
950                                 return 1;
951 
952                         /* If we get done or error, break out */
953                         if (rep->type == NLMSG_DONE || rep->type == NLMSG_ERROR)
954                                 break;
955                 }
956         }
957         return -1;
958 }

不,与连续阻塞读取相比,使用 select()poll() 等 I/O 多路复用系统在单个套接字上侦听数据不会获得更好的性能那个插座。

性能可能会因平台而异(在本例中 Linux),但应该不会更快。

代码使用 select 的主要原因似乎是它的超时能力。它允许超时读取而无需实际修改套接字的超时(SO_SNDTIMEOSO_RCVTIMEO)[或者如果套接字甚至支持超时]。