pthread退出时运行函数

时间:2012-03-08 04:12:11

标签: c++ c pthreads threadpool

我有一个C ++应用程序,我在其中创建pthread来运行用户提供的函数。我希望能够在线程退出时以某种方式发出警报,以便我可以从我用来保留线程的pthread数组中删除它。有没有办法做到这一点,或者该功能是否应该设置一些“神奇的价值”。因为我生成pthreads的主代码是在某种runloop中,所以我可以很容易地检查退出条件。


另外,使用std::vector<pthread_t>过度使用来跟踪我的线程是否过载?线程数不一定是任何类型的常量,许多线程或极少数线程可以运行。或者是否有另一个STL容器可以用于这些添加和删除(总是在一端添加,几乎在任何地方删除)。是否有其他结构可以跟踪pthreads?堆栈或列表是否就在这里?还是一个标准的C阵列,最大限度的慷慨?由于问题的本质,我还可以维护一个固定大小的工作线程数组,我传递给必须执行的用户函数。这是一个很好的解决方案吗?

很抱歉这个长期困惑的问题,但我只使用动态语言中的线程,这绝不是一个问题。


编辑(2012年8月3日): 在阅读@ jojojapan的回答后,我决定使用各种线程池。在我的结构中,我有一个生产者(runloop中的一个线程)和许多消费者(池中的工作线程)。是否存在针对多线程单生产者多消费者使用的数据结构?或者我只是在std::queue上使用pthread_mutex_t吗?

3 个答案:

答案 0 :(得分:3)

  1. 您可能需要考虑的一个选项是在完成任务后不会实际结束和删除线程,而是让它们保持活动并让它们等待新任务分配给他们。你可以通过做两件事来完成这个任务:

    1. 在线程中使用(几乎)无限循环
    2. 使用并发队列或其他技术使其等待另一个线程发出信号。在几个SO问题中讨论了设计模式和策略,例如this one
  2. 如果您确实想在线程结束后发送信号,则可以在线程到达之前使用pthread_cond_t并在其上调用pthread_cond_signal return声明。当然,假设有一些其他线程正在运行,等待这些信号,并通过从向量中删除相应的线程来对它们进行操作。有关用法的详细信息,请参见相应的手册页,但也在this SO post

  3. 与评论和问题的已编辑部分相关的

    修改

    1. 关于工作线程数:这取决于线程使用的资源最多。如果这些线程的作用主要是计算和一点内存访问,换句话说,如果它们受CPU限制,那么使用尽可能多的线程就可以了解CPU(特别是有一定数量的内核,你的CPU在开始减速之前可以运行的每个核心的(硬件)线程的数量。你正在创建的线程(软件线程)应该是多少,或者可能多一些(最多两倍)根据{{​​3}})),硬件线程是合理的。但是,如果您的线程大量使用内存(内存限制)或硬盘(IO绑定)或其他资源(如网络,NFS或其他服务器),您可能希望按顺序减少线程数(a )不要让它们相互阻挡,并且(b)不要对某些资源施加不合理的负担。确定正确的线程数可能是一个试验问题,保持数量可配置通常是一个好主意。

    2. 关于存储工作任务的最佳数据结构:我在上面进一步引用的帖子的评论中提到的what @Tudor says here可能非常好。不过,我自己没试过。但是,如果你想保持简单,标准std::queue,甚至只是std::vector都不是一个糟糕的选择,如果你使用信号/互斥技术正确保护它们。

答案 1 :(得分:1)

考虑完全改变策略并使用现有的线程池库。他们会为你做的工作,你会节省很多不那么有趣的调试。

Boost.thread池是众多link之一。

答案 2 :(得分:1)

一种简单的方法是使用管道。

在产生线程之前打开管道。将管道fd作为线程数据的一部分传递。在线程退出之前,它将pthread_self()写入管道。在管道的读取端有主要或单独的线程。它读取死线程的tid并立即执行pthread_join。 (如果它是一个单独的收割者线程,它可以阻止管道读取;如果它在主要部分只是使它成为你的选择/民意调查的一部分。)

如果不需要,这使您可以灵活地不使用数据结构来保存TID。如果你想保存它们,那么列表或地图是比矢量更好的选择。

如果你有主要的线程和一个单独的“收割者”线程收集它们并且你想将它们保存在某种结构中,那么你需要同步访问两者之间的结构。