C++ 实现一个简单的线程池

C++ 实现一个简单的线程池,c++,windows,multithreading,threadpool,C++,Windows,Multithreading,Threadpool,我目前需要一个简单高效的线程池实现。我在这里搜索过,也在谷歌上搜索过,找到了很多有趣的链接,但到目前为止,我还没有找到合适的链接。我在web上发现的大多数实现要么太复杂,要么缺少我需要的一些关键特性 另外,我不想使用我不懂的代码,所以我决定自己编写代码(有时重新发明轮子可以帮助我在知识和经验方面向前推进)。我当然理解线程池背后的基本思想,但一些实现细节对我来说仍然有些不清楚。这可能是因为我需要的线程池有点特殊。让我来描述一下。我有一个任务,它在一个特定的(大的)缓冲区上执行了数十万次。我已经测量

我目前需要一个简单高效的线程池实现。我在这里搜索过,也在谷歌上搜索过,找到了很多有趣的链接,但到目前为止,我还没有找到合适的链接。我在web上发现的大多数实现要么太复杂,要么缺少我需要的一些关键特性

另外,我不想使用我不懂的代码,所以我决定自己编写代码(有时重新发明轮子可以帮助我在知识和经验方面向前推进)。我当然理解线程池背后的基本思想,但一些实现细节对我来说仍然有些不清楚。这可能是因为我需要的线程池有点特殊。让我来描述一下。我有一个任务,它在一个特定的(大的)缓冲区上执行了数十万次。我已经测量过,如果我使用线程来执行此任务,性能会更好-缓冲区被分割成子缓冲区,每个线程在子缓冲区上执行其任务并返回结果。然后将所有线程的所有结果相加,给出最终的解决方案

然而,由于这是经常做,我失去了宝贵的时间,因为这么多的线程被创建(因为线程创建带来的开销)。所以我希望有一个线程池来执行这个任务,而不是每次都创建一组新的线程

更清楚地说,到目前为止,我掌握的是:

  • 将缓冲区拆分为N个大小相同的子缓冲区
  • 对于每个子缓冲区,创建一个线程并在子缓冲区上运行它
  • 等待所有线程完成(WaitForMultipleObjects),将结果添加到一起并销毁线程
  • 重复
我想实现的是:

  • 将缓冲区拆分为N个大小相同的子缓冲区
  • 将每个子缓冲区分配给线程池中的一个线程(该线程池正好有N个线程)
  • 线程完成后,让它休眠,直到另一个任务准备就绪
  • 当所有线程完成(和休眠)后,将它们产生的结果加在一起
  • 通过唤醒线程并为其分配新任务来重复上述操作
正如您所看到的,这是一个特殊的线程池,因为我需要等待线程完成。基本上,我想摆脱一直创建线程的开销,因为程序要经过数十万次迭代,所以它可以在其生命周期中创建和销毁数以百万计的线程。好消息是线程之间根本不需要任何同步,它们都有自己的数据和结果存储位置。但是,我必须等到所有线程都完成并且我有了最终的解决方案,因为下一个任务取决于上一个任务的结果

我的主要问题是线程的管理:

  • 新任务完成后,我如何让线程“睡眠”并唤醒它们
  • 如何等待所有线程完成
如果有任何帮助,我将不胜感激。如果我不够清楚,也可以自由提问。谢谢

新任务完成后,如何使线程“休眠”并将其唤醒 准备好了吗

根据您的情况(在某些情况下,您可能需要使用条件变量或自动/手动重置事件),您可以使用互斥或信号量使线程彼此等待或在发生事件时唤醒

如何等待所有线程完成

您必须在每个线程上使用
join()
,等待它完成。因此,如果您有一个线程集合,您可能希望遍历并调用仍在运行的每个线程上的join


另请注意:线程池已经存在,您可以使用Boost.Threadpool之类的工具,而不是重新发明轮子。

您看过其他线程池实现吗?比如说。你想要完成的并不完全是新的。让线程等待新任务的一种方法是阻塞互斥体,并在另一个任务准备就绪时解除该互斥体的阻塞。您还可以让线程通过从线程返回父线程的某种通知来通知它们已完成

在我的工作中,我一直大量使用线程池/线程,并一直使用ØMQ进行线程间的通信,这允许线程在准备好进行新工作时阻止来自ØMQ的
read()
请求


通过一点研究,再加上一点时间和精力,你应该能够弄清楚如何构建或利用现有的框架/工具来构建你需要的东西。然后,当您有一些代码遇到问题时,您可以返回到

对于我来说,与线程通信的首选方式是通过条件变量。因为您可以定义所需的条件,并在条件发生变化时发出信号。在您的例子中,您可以将它与传递子缓冲区的队列相结合,这样每个线程都会在队列为空时等待。然后可以将结果放在另一个队列上,其中管理队列正在等待,直到所有线程都将结果发布到该队列(对该队列的引用与子缓冲区一起作为请求传递)。

',因为我需要等待线程完成。”-不完全。您希望处理作业中最后一个任务的线程提供作业完成通知。完成通知是ADPool的正常功能,否则原始线程将无法处理一组完整的结果。池通常同时处理多个任务/任务层次结构,因此完成通知方法应该是线程无关的-no join()或类似的方法。此外,没有WaitForMultipleObject()-使用难以管理且限制为64个对象的同步对象数组

T