gpt4 book ai didi

c++ - 线程构建 block (TBB) `` `enqueue ``` 任务生命周期

转载 作者:行者123 更新时间:2023-11-30 04:07:37 29 4
gpt4 key购买 nike

如果在函数中使用tbb::task::enqueue 将任务入队,然后函数在任务执行前超出范围,任务会丢失吗?

如果是这样,如何避免?例如,如果您想将一个任务放入一个短暂的事件处理程序回调中,该回调将很快超出范围,而调度程序直到稍后才会执行该任务怎么办?

另外,enqueue函数有容量限制吗?如果有超过一定数量的待处理任务,它会丢弃任务吗?

最佳答案

tbb::task 是一个对象。与任何其他 C++ 对象一样,同样的 C++ 生命周期规则(和危险!)适用于 tbb::task。对于所讨论的情况,请确保以不受函数返回影响的方式捕获任务中的信息。例如,捕获局部变量的值,而不是引用。

这是一个使用 lambda 表达式显示问题的程序。它借Alexey Kukanov's lambda_task

#include <tbb/tbb.h>

template<typename F>
class lambda_task : public tbb::task {
F my_func;
/*override*/ tbb::task* execute() {
my_func();
return NULL;
}
public:
lambda_task( const F& f ) : my_func(f) {}
};

template<typename F>
void tbb_enqueue_lambda( const F& f ) {
tbb::task::enqueue( *new( tbb::task::allocate_root() ) lambda_task<F>(f) );
}

void LaunchOneTask( int i, int j ) {
if( i%1000000==0 )
[i,&j]{printf("Launching i=%d j=%d\n",i,j);}();
tbb_enqueue_lambda( [i,&j]{ // Deliberate mistake for j!
printf("Hi from lambda: i=%d j=%d\n",i,j);
sleep(1);
} );
}

int main() {
for( int i=0; i<1000000000; ++i ) {
LaunchOneTask(i,i);
}
}

如果运行它,您会看到“Launching...”行正确打印了 ij,但是“Hi from...”行打印j错误 值。这是因为 lambda 已通过引用 (&j) 捕获了 j,并且该引用指向一个在任务运行前消失的左值。

据我所知,tbb::task::enqueue 的容量限制是系统内存的容量限制。程序员应确保不会发生这种情况。

关于c++ - 线程构建 block (TBB) `` `enqueue ``` 任务生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22389101/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com