在服务器/客户端设置中,我有一台服务器连接客户端,在少数(目前为4)的不同套接字上。目前我使用select和计算的set_size,但是在使用FD_SETSIZE值之前有什么上限?
以下是一些代码示例来说明这一点。首先构建集合:
FD_ZERO(&set);
FD_SET(socket1, &set);
FD_SET(socket2, &set);
FD_SET(socket3, &set);
FD_SET(socket4, &set);
以下是计算set_size的方法:
set_size = MAX(socket1, socket2);
set_size = MAX(set_size, socket 3);
set_size = MAX(set_size, socket4);
set_size += 1;
用法:
while ((cnt = select(set_size, &set, NULL, NULL, &t)) != -1 || errno == EINTR) {
if (cnt > 0)
// Do different stuff depending what socket is active
else
// Keep everything alive and add the sockets to the set again
}
最近我不得不添加两个新套接字,我可能需要在将来添加更多套接字。您何时使用FD_SETSIZE而不是计算的set_size?
答案 0 :(得分:1)
我从来没有对此感到担心,因为与首先使用select()
的性能损失相比,它似乎会产生很小的差异。
话虽如此,我认为总是值得计算正确的值,因为计算起来并不是很昂贵:如果你按照你的建议将当前set_size
保留在局部变量中,那么 O(1每次添加fd(即比较和可能的更新)时,常量非常低。。删除fd也是 O(1),除了它是列表中的最后一个(在这种情况下它是 O(set_size
),但通常更好)。另一方面,不计算set_size
意味着每次调用FD_SETSIZE
时内核都必须遍历所有select
个条目。由于set_size
可能比FD_SETSIZE
小很多,因此提供较小的值是值得的。即使set_size
接近FD_SETSIZE
,计算set_size
也是如此便宜,以至于它几乎总是值得的。
当然,如果你担心这种程度的表现,你需要看poll()
而不是select()
。更好的是,您需要查看epoll
和kqueue
,除非这些功能不可移植,因为这些功能分别仅适用于Linux和FreeBSD(包括MacOS)。