如何告诉c++并发运行时重用前一个线程来执行任务

how to tell the c++ concurrency runtime to reuse the previous thread for task continuations

本文关键字:一个 线程 执行任务 c++ 何告诉 并发 运行时      更新时间:2023-10-16

我使用visual c++并发运行时创建了一个任务,然后在它上面安排了四个延续

#include <iostream>
#include <thread>
#include <ppltasks.h>
int main()
{
    concurrency::create_task([]
    {
        std::cout << std::this_thread::get_id() << std::endl;
    })
    .then([]
    {
        std::cout << std::this_thread::get_id() << std::endl;
    })
    .then([]
    {
        std::cout << std::this_thread::get_id() << std::endl;
    })
    .then([]
    {
        std::cout << std::this_thread::get_id() << std::endl;
    })
    .then([]
    {
        std::cout << std::this_thread::get_id() << std::endl;
    });
    std::cin.get();
}

输出如下

29432
29432
25096
25668
42488

注意,这4个延续并没有被调度到与初始任务相同的线程上。是否有一种方法可以在与初始任务相同的线程上调度延续?我相信这在c#中可以通过使用TaskContinuationOptions实现。ExecuteSynchronously选项。

通常,可以使用task_continuation_context控制执行延续的上下文,正如MSDN文档所描述的那样。然而,同样的文档也提到:

只有在Windows Store应用程序中使用这个类才有用。对于非Windows Store应用程序,任务延续的执行上下文由运行时决定,而不是可配置的。

从你的代码片段看来,当你使用并发运行时,你不是使用它从Windows商店应用程序。因此,上下文将有效地始终是任意的。

还有一个问题,为什么你要显式地在同一个线程上运行后续任务作为第一个任务:为什么不把这些任务的代码放在第一个任务,那么?延续的意义在于回到一个特定的线程,以便继续在后台任务中完成的工作——也就是说,第一个任务必然是你想要做的后台工作,而延续是从主线程对该工作做出反应的。如果你想留在后台线程上,那就留在那里,不要把工作放到continuation中。(然而,正如上面提到的,因为这不是一个Windows Store应用程序,所有这些延续和任务运行在一个任意的上下文中;运行时只会选择一个方便的可用线程)

相关文章: