如何在 C++ 中正确销毁线程池

Posted

技术标签:

【中文标题】如何在 C++ 中正确销毁线程池【英文标题】:how to properly destory a thread pool in c++ 【发布时间】:2020-11-07 15:36:52 【问题描述】:

所以我使用了一个变量

std::vector<pthread_t> preallocatedThreadsPool;

保存所有 pthreads, 然后我使用 for 循环

preallocatedThreadsPool.resize(preallocatThreadsNumber); // create a threadpoOl
for(pthread_t i : preallocatedThreadsPool) 
    pthread_create(&i, NULL, threadFunctionUsedByThreadsPool, NULL);

创建线程池,

问题是我如何真正破坏它,例如,当我向程序发送信号时,我需要手动处理程序以停止所有预先分配的 pthreads?

我尝试使用另一个 for 循环并在 for 循环内调用pthread_exit(i), 但是IDE,告诉我for循环只会执行一次,这显然不起作用

我尝试使用 preallocatedThreadsPool.clear() 来清理向量,但是当我使用 gdb工具调试一下,在info threads里面,线程还在吗?

在我的情况下,有没有一种好方法可以销毁所有预先分配的 pthread?

【问题讨论】:

请不要标记不相关的语言。 (固定) Formget pthreads 并使用std::thread 是整个程序终止,还是你的意思是你想停止池中的线程而其他线程继续运行?您是否需要某种有序的、先完成的-您正在做的-现在关闭,还是可以接受强制硬停止? @John Bollinger。就像我提到的,例如,我的程序是一个服务器,它在后台作为守护程序服务运行,当我发送一个信号(比如 sighup)来重新配置服务器时,在这个 sighup 处理程序中,我必须手动清空这个 preallocatedThreadsPool ,然后重新创建它以再次重新启动服务器 【参考方案1】:

线程必须自行退出。你不能退出另一个线程。

您可以使用pthread_join 等待线程退出,或使用pthread_detach 表示您永远不会调用pthread_join。您必须调用其中的一个,否则它会泄漏线程。 pthread_join 销毁线程; pthread_detach 不会破坏线程(显然),但它允许线程在退出时自行破坏。

由于这是一个线程池,因此您必须有一个队列,其中包含您希望池中的线程执行的操作。您可以将特殊的“请退出”项添加到队列的末尾(或开头),然后等待线程退出。使线程在队列中看到“请退出”项时退出。

【讨论】:

【参考方案2】:

这都是关于线程同步的。正确的方法是你必须有一个全局标志(例如条件变量或 Win32 事件),线程必须定期检查,如果设置,则终止。当线程退出时,您还必须等待它退出,因此每个线程都应该在“我完成”时发出另一个事件。

之后,分配给 pthread 或 std::thread 或 CreateThread 的任何“句柄”都可以被销毁。在 std::thread 中,您可以分离并忘记句柄。

即使您可以通过诸如 TerminateThread 之类的函数立即终止线程(pthreads 中应该有类似的东西),但这是非常糟糕的,因为您可能会泄漏内存。

【讨论】:

以上是关于如何在 C++ 中正确销毁线程池的主要内容,如果未能解决你的问题,请参考以下文章

并发编程系列之如何正确使用线程池?

无论如何要知道何时销毁池线程(或 ThreadStatic 成员)?

在 Openmp (C++) 中销毁线程

C++线程池

C++线程池

如何确定线程池中线程数量