2

在服务器/客户端设置中,我有一个服务器与少数(目前为 4 个)不同套接字上的客户端连接。目前我使用带有计算 set_size 的 select,但是在值得使用 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?

4

1 回答 1

2

我从不担心这一点,因为与最初使用的性能损失相比,它似乎会产生非常小的差异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(). 更好的是,您需要查看epolland kqueue,但它不是可移植的,因为这些功能分别仅在 Linux 和 FreeBSD(包括 MacOS)上可用。

于 2012-11-07T16:26:38.767 回答