如何完全关闭 TBB 代码中的线程



注意:这不是这个问题的副本。

给定一个与TBB并行的复杂软件,如何完全关闭线程?我知道task_scheduler_init:

int nthreads = tbb::task_scheduler_init::default_num_threads();
const char* cnthreads = getenv("TBB_NUM_THREADS");
if (cnthreads) nthreads = std::max(1, atoi(cnthreads));
tbb::task_arena arena(nthreads, 1);
tbb::task_scheduler_init init(nthreads);

但是,此解决方案(与此相关(不会关闭线程。TBB 仍然创建大量线程,nthreads只是使其中一些线程未被使用。此外,如果有nthreads = 1,TBB 实际上会创建 1 个额外的线程 - 总共 2 个线程与主线程一起。

是的,在某些情况下,您希望真正完全关闭线程,同时保持TBB代码的活动。我目前的解决方案是围绕 tbb 的草率包装器:

namespace hddm {
bool enableTBB = true;
class task_group {
unique_ptr<tbb::task_group> tbb;
public :
task_group() {
if (enableTBB)
tbb.reset(new tbb::task_group());
}
template<typename F>
void run(const F& f) {
if (tbb)
tbb->run(f);
else
f();
}
void wait() {
if (tbb)
tbb->wait();
}
};
class task_arena {
unique_ptr<tbb::task_arena> tbb;
public :
task_arena(int nthreads, int dedicated) {
if (enableTBB)
tbb.reset(new tbb::task_arena(nthreads, dedicated));
}
template<typename F>
void execute(const F& f) {
if (tbb)
tbb->execute(f);
}
};
class task_scheduler_init {
unique_ptr<tbb::task_scheduler_init> tbb;
public :
task_scheduler_init(int nthreads) {
if (enableTBB)
tbb.reset(new tbb::task_scheduler_init(nthreads));
}
};
class parallel_for {
public :
template<typename F>
parallel_for(const tbb::blocked_range<int>& r, const F& f) {
if (enableTBB)
tbb::parallel_for(r, f);
else
f(r);
}
};
} // namespace hddm

希望TBB/英特尔专家能推荐更好的解决方案,谢谢!

自英特尔 TBB 4.3 更新 5 以来,已不推荐使用tbb::task_scheduler_init(请参阅文档和此论坛主题(。现在,您可以在全局范围内使用 tbb::global_control 类修改此行为。

为了后代,

#include <tbb/global_control.h>
// somewhere
tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1);

https://spec.oneapi.com/versions/0.5.0/oneTBB/task_scheduler/tbb_global_control.html

最新更新