pthread退出时运行函数
Run function when pthread exits
我有一个C++应用程序,我在其中创建pthread来运行用户提供的函数。当线程退出时,我希望能够以某种方式得到提醒,这样我就可以将其从用于保留线程的pthread数组中删除。有没有办法做到这一点,或者函数应该设置一些"神奇的值"。因为我产生pthreads的主要代码是在某种运行循环中,所以我可以很容易地检查退出条件。
此外,使用std::vector<pthread_t>
来跟踪我的线程是否是一种过载?线程数量不一定是任何类型的常量,可能有很多线程或很少线程在运行。或者,是否有另一个STL容器可以用于这些添加和删除(添加总是在一端,删除几乎在任何地方)。是否有其他结构可以跟踪pthreads?堆栈或列表就在这里吗?还是一个标准的C数组,有一个慷慨的最大优点?由于问题的性质,我还可以维护一个固定大小的工作线程数组,将必须执行的用户函数传递给这些线程。这是一个好的解决方案吗?
很抱歉出现这个长期困惑的问题,但我只在动态语言中处理过线程,这永远不会成为问题。
编辑(2012年8月3日):在阅读了@jojojapan的答案后,我决定使用某种线程池。在我的结构中,我有一个生产者(运行循环中的一个线程)和许多消费者(池中的工作线程)。有没有一个数据结构是为多线程的一个生产者多个消费者所使用的?或者我可以只使用带有pthread_mutex_t
的std::queue
吗?
-
您可能需要考虑的一个选项是,在线程完成任务后,不实际结束并删除它们,而是保持它们的活动状态,并让它们等待新任务分配给它们你可以通过做两件事来实现这一点:
- 在线程中使用(几乎)无限循环
- 使用并发队列或其他技术,让它们等待另一个线程发出信号。设计模式和策略在几个SO问题中进行了讨论,例如本问题
-
如果您真的想在线程结束后发送信号,那么可以使用
pthread_cond_t
并在线程到达其return
语句之前对其调用pthread_cond_signal
。当然,这是假设有其他线程在运行,等待这些信号,并通过从向量中删除相应的线程来对其进行操作。有关用法的详细信息,请参阅相应的手册页,也可在本SO帖子中找到。
编辑与评论和问题编辑部分相关的内容:
-
关于工作线程的数量:这取决于线程使用最多的资源。如果这些线程主要做的是计算和一点内存访问,换句话说,如果它们是CPU绑定的,那么使用尽可能多的线程是有意义的(特别是,有一定数量的内核,以及每个内核可以运行的(硬件)线程数,然后它们开始相互减慢速度。你正在创建的线程(软件线程)应该是一样多,或者可能更多(根据@Tudor在这里的说法,最多是硬件线程的两倍是合理的)。但是,如果线程大量使用内存(内存绑定)或硬盘(IO绑定)或其他资源,如网络、NFS或其他服务器,则可能需要减少线程数量,以便(a)不使它们相互阻塞,(b)不在某些资源上施加不合理的过多负载。确定正确的线程数量可能是一个实验问题,保持数量可配置通常是一个好主意。
-
关于存储工作任务的最佳数据结构:我在上面引用的帖子的评论中提到的并发有界队列可能非常好。不过我自己还没试过。但是,如果你想保持简单,如果你使用信号/互斥技术正确地保护它们,标准的
std::queue
,甚至简单的std::vector
都不是一个糟糕的选择。
考虑完全更改策略并使用现有的线程池库。他们会为你做这项工作,你会省去很多不那么有趣的调试。
Boost.线程池是众多链接之一。
在生成线程之前打开管道。将管道fd作为线程数据的一部分传递。在线程退出之前,让它将其pthread_self()
写入管道。在管道的读取端有主螺纹或单独螺纹。它读取死线程的tid并立即执行pthread_join。(如果它是一个单独的收割者线程,它可以直接阻塞管道读取;如果它是主线程,则将其作为选择/轮询或其他线程的一部分。)
这使您可以灵活地在不需要的情况下根本不使用数据结构来保存TID。如果你确实想保存它们,那么列表或地图是比矢量更好的选择。
如果您有main启动线程和一个单独的"reaper"线程来收集它们,并且您想将它们保存在某个结构中,那么您需要在两者之间同步对该结构的访问。
- 如何在函数运行时逐个显示列表项
- C++:链接库两次,全局构造函数运行两次吗?
- C 从类的构造函数运行Boost线程
- 回文过滤器,函数运行良好,但main()无法编译
- 如何在 c++ 中将机器代码作为函数运行
- 将 PHP 中的 $_POST 变量传递给由 exec() 函数运行的C++程序
- 如何在 C++ 中使用一个 System() 函数运行 2 个命令
- 为什么用空函数运行std::线程会花费大量内存
- 在函数运行时停止 Wt C++函数
- C 构造函数运行时/编译时间
- 是否可以在析构函数运行时不销毁 obj
- CArray的析构函数运行大约需要30秒
- 如何使这个递归函数运行得更快
- 如何在Visual studio C++中检查函数运行时间
- C++函数运行,即使它不应该运行?
- 参数的可变数量函数运行时错误
- boost::asio::io_service析构函数运行很长时间
- 具有变量参数的函数运行时错误
- C++析构函数运行时错误:无法munmap
- 如何在 MEX 函数运行时制作它 printf?