【问题标题】:How can I create my own thread pool on legacy c++?如何在旧版 C++ 上创建自己的线程池?
【发布时间】:2015-12-13 04:03:57
【问题描述】:

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

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

我非常感谢任何可以帮助我获得创建自己的线程池所需的经验和知识的材料或指南。

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

根据要求:关于问题:

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

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

关于您可以检查的代码示例:How can I reduce the effect of pthread_join. Mingw32, c++

但我意识到是线程创建,而不是导致性能恶化的 thread_join。

【问题讨论】:

  • 您能更具体地说明您遇到的问题吗?就像游泳池本身一样?工作队列?线程?把它们放在一起?
  • 如果您对 Boost 没问题,那么使用 Boost.Asio 进行基于任务的多线程处理是一种非常有效(和跨平台)的方法:stackoverflow.com/questions/19500404/…
  • 我希望这个编辑能更好地澄清问题。我会尝试 boost 解决方案,但我的项目规模有限,所以我不能包含大型库。
  • 对于计算昂贵的项目,我建议不要发明轮子,也不要试图搞乱低级多线程,而是使用基于任务的多线程,它实际上在其实现中使用线程池。最好的实现之一是英特尔线程构建块:threadingbuildingblocks.org
  • 我查看了 threadingbuildingblocks.org,它有 42 MB,非常大。

标签: c++ multithreading pthreads mingw threadpool


【解决方案1】:

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

首先,有几句话。

  • pthread_create 非常轻量级。这不太可能是一个真正的瓶颈。如果您的计算时间与创建线程所需的时间相当,那么您可能不需要线程一开始。
  • C++11 是普通的 C++。 C++03 被称为 ARCHAIC。我强烈建议您重新考虑项目的“约束”(因为您似乎没有使用外部库,所以 ABI 不兼容对您来说应该不是问题),并放弃使用 11 年、过时且不足的编译器。

现在,到线程池。基本线程池包含 3 个主要部分:传入消息队列、传出消息队列和一组为这些队列服务的线程。根据设计,这些消息可能是真正的消息(即字符串说“亲爱的线程,请计算 5 + 10”),或者它可以是线程调用的可调用事物。类型擦除的函数对象在这里效果最好。所以,当消息是文本时,线程函数会有一堆 if() 语句来处理不同的消息,当它是一个可调用对象时,它会简单地调用这个可调用对象。短信更易于维护,因为您在文本本身中拥有您需要关心的所有内容。另一方面,可调用对象具有生命周期,您应该考虑到这一点 - 例如,将局部变量作为可调用对象将注定是一场灾难。

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

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

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-30
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多