服务器多线程矫枉过正?

时间:2010-03-03 15:05:59

标签: c# multithreading tcpclient waithandle manualresetevent

我正在创建一个服务器类型的应用程序,它将通常监听外部客户端的连接,并在连接时处理请求等。

目前,我的实现每次客户端连接时都会创建一对线程。一个线程只是从套接字读取请求并将它们添加到队列中,第二个线程从队列中读取请求并处理它们。

我基本上都在寻找关于你是否认为所有这些线程都是矫枉过正的意见,更重要的是这种方法是否会给我带来问题。

重要的是要注意,这些线程大多数时间都处于空闲状态 - 我在两个线程中使用等待句柄(ManualResetEvent)。 Reader线程等待消息可用,如果有,则读取它并将其转储到Process线程的队列中。 Process线程等待读者发出消息在队列中的信号(同样,使用等待句柄)。除非特定客户端真正锤击服务器,否则这些线程将等待。这很贵吗?

我做了一些测试 - 有1000个客户端连续不断地唠叨 - 服务器(所以,2000多个线程),它似乎很好地应对。

2 个答案:

答案 0 :(得分:1)

我认为您的实施存在缺陷。这种设计不能扩展,因为创建线程很昂贵,并且可以创建多少线程。 这就是大多数此类实现使用thread pool的原因。这样可以轻松地限制最大线程数量,同时轻松管理新连接并在工作完成后重新使用线程。

如果你正在用你的线程做的就是将项目放入队列中,那么使用 ThreadPool.QueueUserWorkItem方法使用默认的.NET线程池。

你没有在你的问题中给出足够的信息来指定明确的但是现在你可能只需要一个其他线程,不断运行清理队列,你可以使用等待句柄来指示什么时候添加了什么。

只需确保同步对您的队列的访问权限,否则事情将会出现严重错误。

答案 1 :(得分:0)

我建议使用以下模式。首先你需要线程池 - 内置或自定义。有一个线程可以检查是否有可供读取的内容,如果有,则会选择Reader线程。然后读取线程进入队列,然后处理线程池中的线程将选择它。它将最小化线程数并最大限度地减少等待状态的时间