终止PPL线程池中的线程

时间:2019-01-31 19:17:05

标签: qt memory-leaks threadpool ppl

Microsoft的PPL库包含强大的并行化概念,并使用线程池来实现它们,因此在运行PPL任务时通常不会创建新线程。但是,似乎没有一种方法可以显式停止线程池中的线程。

之所以要显式停止线程是因为Qt。一些Qt方法将信息存储在分配的类实例中,并且指向该类实例的指针存储在线程本地存储中。仅当线程以正常方式停止时,才会清理此内存。如果没有,Qt将无法清理此分配的内存。

将PPL与Qt结合使用意味着该内存在出口时没有被适当地重新分配,这本身不是问题,但是不幸的是,我们的内存分配库将此未分配的内存报告为内存泄漏(请参阅{{3} },以解决类似问题。

我们注意到,如果我们自己创建线程(因此不使用PPL线程池),则不会报告泄漏。如果使用PPL,则会报告泄漏。

所以,问题是:有没有一种方法可以显式停止PPL线程池中的线程?

1 个答案:

答案 0 :(得分:-1)

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;
}

但是,为了帮助您更多-您可以向我们提供一些源代码吗?