c++ - 终止 PPL 线程池中的线程
问题描述
Microsoft 的 PPL 库包含强大的并行化概念,并使用线程池实现它们,因此在运行 PPL 任务时通常不会创建新线程。但是,似乎没有办法显式停止线程池中的线程。
我想显式停止线程的原因是因为 Qt。一些 Qt 方法将信息存储在分配的类实例中,指向该类实例的指针存储在线程本地存储中。只有当线程以优雅的方式停止时,才会清理此内存。如果没有,Qt 不能清理这个分配的内存。
将 PPL 与 Qt 相结合意味着该内存在退出时没有适当地释放,这本身不是问题,但不幸的是,这种未释放的内存被我们的内存分配库报告为内存泄漏(请参阅是否有人在使用 valgrind 和 Qt?对于类似的问题)。
我们注意到,如果我们自己创建线程(因此不使用 PPL 线程池),则不会报告泄漏。如果我们使用 PPL,则会报告泄漏。
那么,问题来了:有没有办法显式停止 PPL 线程池中的线程?
解决方案
PPL 在 C++ 中遵循与 C# 中的异步编程非常相似的概念。
总体思路是“合作取消”——你可以要求一个线程停止,线程决定什么时候可以取消。您不应终止任务/线程,以免线程不会在未定义的指令处停止。
在这里,您可以看到如何使用 ppl 停止线程/任务的示例:
include <ppltasks.h>
#include <concrt.h>
#include <iostream>
#include <sstream>
using namespace concurrency;
using namespace std;
bool do_work()
{
// Simulate work.
wcout << L"Performing work..." << endl;
wait(250);
return true;
}
int wmain()
{
cancellation_token_source cts;
auto token = cts.get_token(); // <-- allow early cancellation, therefore share a cancellation_token
wcout << L"Creating task..." << endl;
// Create a task that performs work until it is canceled.
auto t = create_task([&]
{
bool moreToDo = true;
while (moreToDo)
{
// Check for cancellation.
if (token.is_canceled()) //<-- check for cancellation in the background thread
{
// Cancel the current task.
cancel_current_task(); //<-- informs the caller, "hey I got it..."
}
else
{
// Perform work.
moreToDo = do_work();
}
}
}, token);
// Wait for one second and then cancel the task.
wait(1000);
wcout << L"Canceling task..." << endl;
cts.cancel();
// Wait for the task to cancel.
wcout << L"Waiting for task to complete..." << endl;
t.wait(); //<-- this is import
wcout << L"Done." << endl;
}
但是为了帮助你更多——你能给我们提供一些源代码吗?
推荐阅读
- iis - 无法在 IIS 中托管的所有网站上访问此站点 ERR_CONNECTION_ABORTED
- python - 为什么我无法在 django 模板中加载 youtube 嵌入 url?
- python - Gunicorn 多个烧瓶工人和绑定任务 celery
- python - Python多进程运行多次
- mysql - 从“x”表返回前“n”值并连接的方法
- java - 如何将android imageview坐标转换为PDFView坐标以在PDF框库中添加电子签名?
- wordpress - /wp-admin 返回“抱歉,您无权访问此页面。” 在为 SSL 终止添加 CDN 之后?
- javascript - 在 firebase firestore 的集合中搜索字段
- json - Chrome 扩展错误:不允许使用尾随逗号,必须引用字典键
- laravel - Laravel 7如何安装语言