线程池实现

时间:2011-03-30 17:59:49

标签: c++ multithreading sockets asynchronous

我想创建一个简单的线程池(在* nix系统上)来处理异步通信服务器上的输入。我有一些问题。起初我只想拥有一个静态的线程数,任意说6。

我应该如何将命令发送到工作线程?

我正在考虑使用简单的套接字通信,就像这样

主线程::发送[(recv)套接字(发送)otherSocket];

然后让我的线程简单地阻止接收呼叫,这是非常低效的吗?

我应该使用图书馆吗?是否有更好的实施方法?

(稍后我将使线程变得动态,我只是认为从一组数字开始会更容易)

3 个答案:

答案 0 :(得分:3)

首先,您应该意识到Windows不仅仅有一个,而是内置了两个线程池API。如果这还不够,I / O完成端口也基本上是线程池变相。因此,可能根本没有理由编写自己的线程池。

除非您计划允许线程在不同的计算机上运行,​​否则我不会使用套接字进行通信。线程的正常意图是它们应该将开销保持在最低限度;插座不适合那个。如果您跨越机器边界,则更多的开销(网络通信)变得几乎不可避免,在这种情况下,使用套接字而不是其他网络API并没有太大的区别。另请注意,对于跨机器工作,通常需要做更多的工作,将数据从一个编组到另一个,依此类推。

假设您坚持使用单个计算机,我会使用某种方式的线程安全队列而不是套接字。我在previous answer中发布了一个您可能会觉得有用的内容。这包括一些示例代码,它们创建一个线程池来为队列中的任务提供服务。

答案 1 :(得分:2)

你应该使用图书馆吗?嗯,当然,否则你将不会在标准C ++中完成任何你想要的东西。这会让你怀疑你想要使用什么平台...你使用的是Windows,还是某种Linux?如果您使用的是Windows,则可以使用Windows线程和Win Socks 2.如果是Linux,您可以尝试使用Posix线程,而对于网络,我并不完全确定。但是,您可以使用Boost库来完成所有这些工作,它应该可以在Windows和Linux操作系统上运行。

就发送消息而言,您可以使用互斥锁作为消息队列,只需要一个接收消息函数来锁定它并添加消息,该消息适用于任何线程上来自套接字的网络传入消息,以及其他希望向该线程发送消息的线程。另外不要忘记,当线程正在处理消息时,您还要锁定互斥锁;无论何时访问该消息队列,都需要锁定它以防止冲突/数据错误。

答案 2 :(得分:2)

由于您使用的是套接字,因此您必须使用select或poll之类的东西来等待套接字活动。因此,对于线程间通信(itc),使用文件描述符的东西将非常有用。这可能是一对或管道或unix域套接字。

然后,您的主线程将接受新的连接并使用您的itc机制将新文件描述符传递给工作线程。然后,工作线程将新的文件描述符添加到select / poll循环中。

如果要连接并等待后端服务器(如数据库),则可以在等待recv完成时决定阻塞,尽管您应该避免这种情况。如果使用状态机并将堆栈回滚到选择外观(将后端文件描述符添加到select / poll循环之后),则服务器将更具响应性。这将使您的主线程更容易控制您的工作线程。如果你聪明,你的线程可以一次处理多个请求,只有少数线程你应该有一个非常可扩展的服务器。

尽量避免为itc使用信号量或互斥量,而是通过itc管道或unix域套接字发送所有请求。在竞争条件下,你会为​​自己节省很多心痛。