多线程服务器设计

时间:2012-01-29 20:48:05

标签: c multithreading network-programming tcpserver

我正在尝试实现一个TCP服务器,它是大型项目的一部分。基本上,服务器应该能够与任意数量的客户端(至少32个)保持TCP连接,并为请求服务的任何客户端提供服务。在我们的场景中,事情是假设一旦客户端连接到服务器,它将永远不会关闭连接,除非发生某种故障(例如运行客户端的机器发生故障)并且它将重复请求服务服务器。所有其他客户端的情况也是如此,每个客户端都将与服务器保持连接并执行事务。总而言之,服务器将同时维护与客户端的连接,同时根据需要为每个客户端提供服务,并且还应该能够接受任何其他想要连接到服务器的客户端连接。

现在我使用berkely套接字API的select()系统调用实现了上述功能,当我们拥有少量客户端(比如10)时,它可以正常工作。但是,当我们在16核计算机上实现服务器时,需要将服务器扩展到最高级别。为此我查看了各种多线程设计技术e-g每个客户端的一个线程等,我认为最好的是线程池设计。现在,当我即将实施时,我遇到了一些问题: 如果我指定主线程接受任意数量的传入连接并在数据结构中保存每个连接文件描述符,并且我有一个线程池,我将如何获取线程来轮询特定客户端是否请求服务或不。设计非常简单,适用于客户端与服务器联系的场景,在获取服务后关闭连接,以便我们可以从池中选择一个线程,为客户端提供服务,然后将其推回池中以便将来进行连接处理。但是,当我们必须服务于维护连接并间歇性地请求服务的一组客户端时,最好的方法是做什么。所有的帮助将非常感激,因为我真的被困在这里。 感谢。

2 个答案:

答案 0 :(得分:2)

使用pthreads,每个CPU一个线程加一个额外的线程。

额外线程(主线程)使用listen()系统调用侦听新连接,使用accept()接受新连接,然后确定哪个工作线程当前具有最少数量的连接,获取锁定/互斥锁对于该工作线程的“挂起连接”FIFO队列,将接受连接的描述符放在工作线程的“挂起连接”FIFO队列中,并向工作线程发送“检查队列”通知(例如使用管道)。 / p>

工作线程使用“select()”,并将数据发送/接收到他们已接受的任何连接。如果/当工作线程从主线程收到“检查队列”通知时,它将获取其“挂起连接”FIFO队列的锁/互斥锁,并将任何新接受的连接添加到其“fd_set”列表中。

1024个连接和16个CPU;你最终可能会有一个主线程等待新的连接(但几乎没有做任何事情,因为你不会期待很多新的连接),16个工作线程每个平均处理64个连接。

答案 1 :(得分:0)

每个客户一个线程几乎肯定是最好的设计。确保在accept中至少有一个线程被阻塞,等待新连接 - 这意味着在接受成功后,您可能需要创建一个新线程,然后再继续它,如果它是最后一个。我发现信号量是一个很好的基元,可以跟踪产生新的监听线程的需要。