如何最小化tcp服务器应用程序中使用的线程数?

时间:2008-08-28 13:07:57

标签: multithreading sockets tcp udp

我正在寻找人们在实现服务客户端TCP(或UDP)请求的服务器应用程序时使用的任何策略:设计模式,实现技术,最佳实践等。

我们假设为了这个问题的目的,请求是相对长寿的(几分钟),并且流量是时间敏感的,因此在响应消息时没有可接受的延迟。此外,我们既处理来自客户端的请求,也正在与其他服务器建立自己的连接。

我的平台是.NET,但由于底层技术与平台无关,我很有兴趣看到任何语言的答案。

4 个答案:

答案 0 :(得分:6)

现代方法是利用操作系统为您复用许多网络套接字,使您的应用程序只能处理与流量的活动连接。

无论何时打开套接字,都会将其与选择器相关联。您使用单个线程轮询该选择器。每当数据到达时,选择器将指示活动的套接字,将该操作移交给子线程并继续轮询。

这样,每个并发操作只需要一个线程。打开但空闲的套接字不会占用线程。

答案 1 :(得分:4)

更具攻击性的方法是使用IO完成端口。 (视窗) 使用IO完成端口,您可以离开操作系统来管理轮询,从而可以在NIC驱动程序支持下使用非常高级别的优化。 基本上,您有一个由OS管理的网络操作队列,并提供在操作完成时调用的回调函数。有点像(硬盘驱动器)DMA但是用于网络。

几年前,Len Holgate在Codeproject上写了关于IO完成端口的eccelent系列: http://www.codeproject.com/KB/IP/jbsocketserver2.aspx

和 我在.net上发现了一篇关于IO完成端口的文章(虽然没看过) http://www.codeproject.com/KB/cs/managediocp.aspx

我还会说,与尝试编写可扩展的替代方案相比,使用完成端口很容易。问题是它们只适用于NT(2000,XP,Vista)

答案 2 :(得分:2)

如果您直接使用C ++和Win32,那么我建议您阅读有关重叠I / O和I / O完成端口的信息。我有一个免费的C ++,IOCP,客户端/服务器框架以及完整的源代码,有关详细信息,请参阅here

由于你正在使用.Net,你应该考虑使用异步套接字方法,这样你就不需要为每个连接都有一个线程;我的博客文章中有几个链接可能是有用的起点:http://www.lenholgate.com/blog/2005/07/disappointing-net-sockets-article-in-msdn-magazine-this-month.html(一些最好的链接在原始帖子的评论中!)

答案 3 :(得分:0)

天儿真好,

我首先看一下你想要用于线程框架的比喻。

可能是“领导者跟随者”,其中一个线程正在侦听传入的请求,当一个新请求进入时,它会完成工作,并且池中的下一个线程开始侦听传入的请求。

或者线程池,其中同一个线程始终在侦听传入请求,然后将请求传递给线程池中的下一个可用线程。

您可以访问Ace Components的Reactor部分以获得一些想法。

HTH。

欢呼声, 罗布