什么是最好的,单线程或多线程服务器?

Dai*_*ail 5 c linux network-programming

我必须创建一个简单的客户端< - >服务器通信来使用C语言(Linux)传输文件.

服务器接受10000端口上的连接,我不知道是否更好地为每个请求创建一个新线程或创建固定数量的线程并使用异步技术.

CASE A:

client --> server --> (new thread) --> process the request

CASE B:

SERVER --> create thread 1 - thread 2 - thread 3

then

client1 --> server --> thread 1
client2 --> server --> thread 2
client3 --> server --> thread 3
client4 --> server --> thread 1
client5 --> server --> thread 2
client6 --> server --> thread 3
Run Code Online (Sandbox Code Playgroud)

在这种情况下,线程1可以处理许多客户端的请求

我的考虑:

情况1:速度更快但浪费了大量内存

情况2:速度较慢但使用较低的内存

我错了吗?

Mih*_*uns 5

如果你考虑检查广泛的HTTP服务器(Nginx的,lighttpd的,阿帕奇),你会发现,那那些使用固定的线程数(所谓的"工作线程",其数额应取决于processsor计数在服务器上)的架构是很多快然后一个使用大线程池.但是,有非常重要的时刻:

  1. "工作者线程"的实现不应该像诱人的那样简单,否则就不会有真正的性能提升.每个线程都应该使用状态机实现每个伪并发,并及时处理多个请求.这里不允许阻塞操作 - 例如,从硬盘驱动器等待I/O获取文件内容的线程中的时间可用于解析对下一个客户端的请求.不过,编写代码非常困难.

  2. 在考虑性能与编码时间与代码支持时,基于线程的解决方案(具有可重用的线程池,因为线程创建是重量级操作)是最佳的.如果您的服务器不应该每秒处理数千个请求,您将能够以非常自然的阻塞方式进行编码,而不会有完全失败的风险.

  3. 您可以注意到,"工作线程"解决方案本身仅为静态数据提供服务,它们将动态脚本执行代理到其他程序.据我所知(可能是错的),这是由于非阻塞处理请求的复杂性以及在其上下文中执行的一些未知动态内容.无论如何,当你谈到简单的文件传输时,这不应该是你的问题.

有限线程解决方案在重负载系统上更快的原因 - 线程http://en.wikipedia.org/wiki/Context_switch是相当昂贵的操作,因为它需要从寄存器保存数据并加载新的数据,只要其他一些线程本地数据.如果你有太多的线程与进程数相比(例如多1000倍),你的应用程序中的大量时间将被浪费在线程之间简单切换.

因此,对您的问题的简短回答是:"不,它与内存使用无关,选择的是所提供的数据类型,计划的请求/秒计数以及在编码上花费大量时间的能力".


Ton*_*ion 0

我会使用预先创建的线程池,并在完成当前正在处理的请求后重新使用它们。创建线程可能会很昂贵,因为它主要涉及对内核的调用。

这里有一个使用 pthreads 的“threadpool”类型项目。也许您可以从那里获得一些关于如何实施的想法。