我对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(
[&]
{
...
});
});