所以在我当前的服务器实现中,目前是这样的:
void loop(){
// step 1: clear set
fd_set readfds;
while(true){
// step 1:
FD_ZERO(readfds);
// step 2:
loop_through_sockets_and_add_active_sockets_to(theset);
// step 3:
switch(select(FD_SETSIZE, &readfds, 0, 0, &tv)) {
case SOCKET_ERROR:
patia->receiveEvent(Error, net::getError());
return;
case 0:
return;
}
// step 4:
loop through sockets and check, using FD_ISSET,
which read fd's have incoming data.
}
}
现在,不清除 fd_set(仅在添加/删除通道时使用 FD_SET、FD_CLR)将是更好的方法。
我的问题是,如何在 select() 之后循环遍历 fd_set,而不检查集合的每个成员是否是集合的一部分,而不使用 FD_ISSET?
我的意思是,当您有 4000 个活动连接时,每当有传入数据时,上述循环都必须经过潜在的 4000 个套接字才能到达正确的套接字。如果所有线程都非常活跃,那么复杂度将是 n^2!
我的问题是,如何在 select() 之后循环遍历 fd_set,而不检查集合的每个成员是否是集合的一部分,而不使用 FD_ISSET?
你不能。
有一个轻微的优化select()
返回就绪描述符的数量,因此,如果您记录已处理的数量,则当您知道已完成所有描述符时,可以停止,而无需到达集合的末尾。
我的意思是,当您有 4000 个活动连接时,每当有传入数据时,上述循环都必须经过潜在的 4000 个套接字才能到达正确的套接字。如果所有线程都非常活跃,那么复杂度将是 n^2!
我不明白你从哪里得到 O(n^2) 。当然,从回来后select()
一旦处理完途中的每个就绪描述符,您就会遍历该集合。如果您有 4,000 个就绪 IO 描述符,则循环遍历内存中 4,000 个 C 对象的数组的开销将相当微不足道。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)