【发布时间】:2019-06-25 08:08:06
【问题描述】:
Microsoft 的 PPL 库包含强大的并行化概念,并使用线程池实现它们,因此在运行 PPL 任务时通常不会创建新线程。但是,似乎没有办法显式停止线程池中的线程。
我想显式停止线程的原因是因为 Qt。一些 Qt 方法将信息存储在分配的类实例中,指向该类实例的指针存储在线程本地存储中。只有当线程以优雅的方式停止时,才会清理此内存。如果没有,Qt 就不能清理这个分配的内存。
将 PPL 与 Qt 结合意味着该内存在退出时没有适当地释放,这本身不是问题,但不幸的是,我们的内存分配库将这种未释放的内存报告为内存泄漏(请参阅Is anyone using valgrind and Qt? for类似的问题)。
我们注意到,如果我们自己创建线程(因此不使用 PPL 线程池),则不会报告泄漏。如果我们使用 PPL,则会报告泄漏。
那么,问题来了:有没有办法显式停止 PPL 线程池中的线程?
【问题讨论】:
-
您是否尝试过更改调度程序(可能使用不同的策略)? docs.microsoft.com/en-us/cpp/parallel/concrt/… 可能会在调度程序分离时销毁池。自 VS 2015 以来,PPL 似乎一直在使用自己的池:docs.microsoft.com/en-us/cpp/parallel/concrt/… 否则,您无法从其外部停止任何线程。您通常会很好地要求线程停止(使用某些事件等)。有一个 TerminateThread API,但通常不推荐使用它(不推荐)。
-
PPL 似乎没有关闭任何资源。我试图跟踪
Concurrency::details::ThreadProxy对象(持有 Windows 线程句柄)的生命周期,但我没有看到正在调用此类的析构函数。从main函数退出后,操作系统会直接杀死所有线程而不进行清理。 PPL 库的代码质量不是最好的。那里没有使用智能指针。
标签: c++ windows winapi threadpool ppl