task_group中的部分任务在主线程上执行,而不是在专用线程上执行

时间:2019-06-08 20:26:14

标签: c++ multithreading tbb parallel-for

我对tbb parallel_for()task_group::run()有疑问。 我有一个使用task_group::run()在线程上启动任务的代码。在此任务中,我使用parallel_for()对函数进行并行化。

另一方面,在主线程上,我执行其他计算,并且在某些时候,我还为其他内容调用parallel_for()。 我的问题是,tbb重用了第二个东西的“主线程”来调用在group之前的代码启动(而不在wait()上调用group)。

就我而言,它会产生问题,我不希望第一个任务在主线程上进行调用。原因是由于UI问题,我有一些代码可以测试我们是否在主线程上,以更新一些UI内容。在第二个parallel_for()期间更新UI会导致在这种情况下出现问题。

下面是代表问题的代码:

using namespace std::chrono_literals;

tbb::task_group group;

auto mainThreadId = std::this_thread::get_id();
std::atomic<bool> needWait(true);
std::atomic<bool> taskOnThreadFinish(false);
group.run(
    [&]
    {
        eastl::vector<int> values(20, 0);
        tbb::parallel_for_each(
            values.begin(),
            values.end(),
            [&](int i)
            {
                while(needWait)
                    std::this_thread::sleep_for(1ms);

                // Should never, ever, never be call on the main thread, but it could be the case in TBB !!!!!!
                assert(mainThreadId != std::this_thread::get_id());

                std::this_thread::sleep_for(1ms);
            });

        taskOnThreadFinish = true;
    });

eastl::vector<int> mainThreadValues(10, 0);
tbb::parallel_for_each(
    mainThreadValues.begin(),
    mainThreadValues.end(),
    [&](int i)
    {
        needWait = false;
        std::this_thread::sleep_for(1ms);
    });

while(!taskOnThreadFinish)
    std::this_thread::sleep_for(1ms);

所以我的问题是:在第二次调用tbb :: parallel_for_each()时如何避免重用主线程?

请注意,使用新的std并行函数/行为的代码效果很好。

更新

使用tbb :: task_arena解决了此问题,因为它隔离了竞技场内的task_group。

tbb::task_group arena;
tbb::task_group group;

...
arena.execute(
    [&]
    {
        group.Run(
            [&]
            {
                ...
            });
    });

0 个答案:

没有答案