我对以下概念感到困扰: 大多数书籍/文档描述了多线程服务器的强大功能,最常见的方法是启动一个新线程来为每个新客户端提供服务。例如。一个线程专用于每个新连接。但是如何在大系统中实际实现呢?如果我们有一台服务器接受来自100000个客户端的请求,它已经启动了100000个线程?这是现实的吗?是否可以在服务器中运行多少个线程?此外,上下文切换和同步的开销不会降低性能吗?它是作为队列和线程的混合实现的吗?在这种情况下,队列的数量是固定的?任何人都可以在这方面给我启发,也许给我一个很好的参考来描述这些?
谢谢!
答案 0 :(得分:3)
常用方法是使用线程池。线程池是已创建线程的集合。当新请求到达服务器时,会从池中为其分配备用线程。处理请求时,线程将返回池中。
根据应用程序的特征配置池中的线程数。例如,如果您有一个受CPU限制的应用程序,则不会需要太多线程,因为上下文切换会降低性能。另一方面,如果您有一个DB或IO绑定的应用程序,您需要更多线程,因为等待的时间很长。因此,更多线程将更好地利用CPU。
谷歌“线程池”,你肯定会发现很多关于这个概念的内容。
答案 1 :(得分:3)
答案 2 :(得分:3)
除了上面的答案,我应该注意到,具有许多传入连接的真正高性能服务器尝试不为每个连接产生一个线程,而是使用IO完成端口,select()和其他异步技术来处理多个套接字在一个线程中。当然,必须特别注意确保一个请求或一个套接字的问题不会阻止同一线程中的其他套接字。
此外,线程管理会占用CPU时间,因此不应为每个连接或每个客户端请求生成线程。
答案 3 :(得分:1)
在大多数系统中使用线程池。这是一个等待传入请求的可用线程池。线程数可以增长到配置的最大数量,具体取决于同时发出的请求数和应用程序的特征。
如果请求到达,则从线程池请求未占用的线程。然后,该线程专用于处理请求,直到请求完成。当发生这种情况时,线程将返回到线程池以处理另一个请求。
由于只有有限数量的线程,因此在大多数服务器系统中,应该尝试尽可能缩短请求的生命周期。请求需要执行的时间越少,线程就可以越快地重新用于新请求。
如果请求在所有线程都被占用时进入,大多数服务器都会为请求实现排队机制。当然队列的大小也是有限的,所以当更多的请求到达而不是排队时,新的请求将被拒绝。
拥有线程池而不是为每个请求启动线程的另一个原因是启动新线程是一项昂贵的操作。最好先预先启动一些线程,然后重新使用它们,然后一直开始新的线程。
答案 4 :(得分:1)
要使网络服务器处理大量并发连接,有几种方法(大多分为“每个连接一个线程”和“每个线程多个连接”类别),请查看the C10K page,这是这个主题的一个很好的资源,讨论和比较很多方法,并链接到它们的进一步资源。
答案 5 :(得分:0)
在大多数情况下,创建10k线程可能效率不高,但可以完成并且可以正常工作。
如果您需要同时为10k个客户提供服务,那么在一台机器上这样做是不可能的,但是可能。
根据客户端的实现,可能是10,000个客户端不需要维护开放的TCP连接 - 根据目的,协议设计可以大大提高实现效率。
我认为适用于高规模系统的解决方案可能非常特定于域名,如果您需要建议,则必须详细解释您的问题域。