pthread退出时运行函数

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


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

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


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

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

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

编辑与评论和问题的编辑部分相关:

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

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

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

Boost.thread池是众多链接之一 。

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

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

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

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