WinSock 下 select() 模型的一个问题


在 Windows Socket 中, 默认 select() 一次只能支持 64个套接字. (Linux 下一个 select() 函数能够管理的套接字多得多. 一般默认就有 4096个. select() 函数接口虽然一样,实现上有巨大差别.) 对于一个服务器程序来说显然太少了. 虽然可以修改FD_SETSIZE的值,但是考虑到栈大小的限制也不宜设置过大的数组长度.

自然而然的,会考虑使用多线程. 如果每个线程管理64个套接字,那么多开几个线程就可以突破 select()的限制.

假设这样一个模型, 主线程只负责调用accpet(),把所有的业务逻辑都放在从线程中,以避免出现连接被拒绝的情况.  主线程accpet()了一个套接字之后,经过负载平衡算法,选中了一个线程,并把新的连接加入到该线程select()函数管理的数组中. 问题是,此时,从线程阻塞在 select() 中. 假设该从线程处理的连接全部都是死连接,并且select()函数没有设置超时时间,那么新加入的套接字将永远无法得到处理.

我能想到的是: 主线程在创建业务线程时,对于每个业务线程都创建一个套接字以之关联,称为事件套接字, 业务现在在select()中同事检测这个套接字的事件. 这样,主线程accept()到新的连接后,写某个线程的事件套接字,这样接可以把业务线程及时唤醒.

总的来说 select() 模型在WinSock下还是有很大限制,和Linux相比64个套接字的最大限制简直如同儿戏,对于服务器程序来说一点意义都没有.还是应该使用 完成端口模型.

相关内容

    暂无相关文章