如何在旧版 C++ 上创建自己的线程池?

How can I create my own thread pool on legacy c++?

由于 pthread_create 的高开销,我遇到了问题。我在互联网上寻找一个好的线程池库,但没有找到适合我的项目的库,或者它们根本不起作用。

我是 c++ 的新手,我的编程技能很基础,但是很好。我编程了很多(超过 5 年),我只是没有做过任何面向对象的项目,甚至没有使用过数据结构。

如果有任何 material 或指南可以帮助我获得创建自己的线程池所需的经验和知识,我将不胜感激。

由于我当前项目的限制,我将在 windows 10 (mingw32) 上使用普通的 c++(不是 C++11),并且我必须避免使用任何 boost 库。

如题:关于问题:

我正在编写一个计算量大的项目。我想让它 运行 更快,所以我决定使用 pthreads。然而,问题是线程创建是在一个循环内,并且 pthread_create 被调用了 64 次。

经过大量研究和尝试,我发现线程池是这里的解决方案,但我花了 3 天多的时间让我在网上找到的实现工作,但无济于事,所以我决定编写自己的线程池实现。

关于您可以查看的代码示例:

但我意识到是线程创建,而不是 thread_join 导致性能下降。

尽管那里有一些评论,但基本的线程池并没有那么复杂。它们比好的记录器更简单,例如 :)

首先,有几点声明。

  • pthread_create 非常轻巧。它不太可能是真正的瓶颈。如果您的计算时间与创建线程所需的时间相当,那么您可能不需要线程。
  • C++11 是标准的 C++。 C++03 被称为 ARCHAIC。我强烈建议你重新考虑 'constraints' 你的项目(因为你似乎没有使用外部库,ABI 不兼容对你来说应该不是问题),并放弃一个 11 岁的、过时的和不充分的编译器。

现在,线程池。基本线程池包含 3 个主要部分:传入消息队列、传出消息队列和一组为这些队列提供服务的线程。根据设计,这些消息可能是真正的消息(即字符串 "dear thread, please compute 5 + 10"),也可能是可调用的东西,线程只调用它。类型擦除的函数对象在这里效果最好。因此,当消息是文本时,线程函数将有一堆 if() 语句来处理不同的消息,当它是可调用的时,它会简单地调用这个可调用的。文本消息更易于维护,因为您在文本本身中拥有您需要关心的一切。另一方面,可调用对象具有生命周期,您应该考虑这一点 - 例如,将局部变量作为可调用对象将是一场灾难。

另一部分是消息队列本身。首先,有两个可行的设计选择——每个线程都有自己的队列,或者有一个共享队列供所有线程使用。第一个的好处是队列上没有争用 - 有一个 reader 和一个 writer。共享队列有争用,但好处是它提供了自然负载平衡 - 线程将在准备好处理新消息时简单地获取消息。

无锁队列通常是用作消息队列的不错选择。