服务器多线程杀伤力过大?
我目前正在创建一个服务器类型的应用程序,它将执行通常的侦听来自外部客户端的连接,并在它们连接时处理请求等。
目前,我的实现在每次客户端连接时都会创建一对线程。第一个线程只是从套接字读取请求并将它们添加到队列中,第二个线程从队列中读取请求并处理它们。
我基本上是在寻找关于您是否认为拥有所有这些线程是否太过分的意见,以及重要的是这种方法是否会给我带来问题。
需要注意的是,大多数时候这些线程都是空闲的 - 我在两个线程中都使用等待句柄 (ManualResetEvent)。 Reader 线程等待消息可用,如果有,则读取该消息并将其转储到 Process 线程的队列中。 Process 线程一直等待,直到读取器发出消息表明队列中有消息(再次使用等待句柄)。除非某个特定的客户端确实正在攻击服务器,否则这些线程将一直等待。这成本高吗?
我做了一些测试 - 有 1,000 个客户端连接,不断地唠叨 - 服务器(所以,2,000 多个线程),它似乎处理得很好。
I'm creating a server-type application at the moment which will do the usual listening for connections from external clients and, when they connect, handle requests, etc.
At the moment, my implementation creates a pair of threads every time a client connects. One thread simply reads requests from the socket and adds them to a queue, and the second reads the requests from the queue and processes them.
I'm basically looking for opinions on whether or not you think having all of these threads is overkill, and importantly whether this approach is going to cause me problems.
It is important to note that most of the time these threads will be idle - I use wait handles (ManualResetEvent) in both threads. The Reader thread waits until a message is available and if so, reads it and dumps it in a queue for the Process thread. The Process thread waits until the reader signals that a message is in the queue (again, using a wait handle). Unless a particular client is really hammering the server, these threads will be sat waiting. Is this costly?
I'm done a bit of testing - had 1,000 clients connected continually nagging - the server (so, 2,000+ threads) and it seemed to cope quite well.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为你的实施是有缺陷的。这种设计无法扩展,因为创建线程的成本很高,而且可以创建的线程数量是有限的。
这就是大多数此类实现使用 的原因线程池。这样可以轻松限制最大线程数,同时轻松管理新连接并在工作完成时重用线程。
如果您对线程所做的只是将项目放入队列中,那么请使用
ThreadPool.QueueUserWorkItem
方法使用默认的 .NET 线程池。您在问题中没有提供足够的信息来明确指定,但也许您现在只需要另一个线程,不断运行清除队列,您可以使用等待句柄在添加某些内容时发出信号。
只需确保同步对队列的访问,否则事情将会出现严重错误。
I think your implementation is flawed. This kind of design doesn't scale because creating threads is expensive and there is a limit on how many threads can be created.
That is the reason that most implementations of this type use a thread pool. That makes it easy to put a cap on the maximum amount of threads while easily managing new connections and reusing the threads when the work is finished.
If all you are doing with your thread is putting items in a queue, then use the
ThreadPool.QueueUserWorkItem
method to use the default .NET thread pool.You haven't given enough information in your question to specify for definite but perhaps you now only need one other thread, constantly running clearing down the queue, you can use a wait handle to signal when something has been added.
Just make sure to synchronise access to your queue or things will go horribly wrong.
我建议使用以下模式。首先,您需要线程池 - 内置或自定义。有一个线程检查是否有可读取的内容,如果有,则选择 Reader 线程。然后读取线程放入队列中,然后处理线程池中的线程将选择它。它将最大限度地减少线程数量并最大限度地减少等待状态的时间
I advice to use following patter. First you need thread pool - build in or custom. Have a thread that checks is there something available to read, if yes it picks Reader thread. Then reading thread puts into queue and then thread from pool of processing threads will pick it. it will minimize number of threads and minimize time spend in waiting state