我很难理解TBB的枚举线程特性。我写了这个小代码来测试TLS
#include <iostream>
#include <vector>
#include "tbb/task_scheduler_init.h"
#include "tbb/enumerable_thread_specific.h"
#include "tbb/task.h"
typedef tbb::enumerable_thread_specific< std::vector<int> > TLS;
class Child: public tbb::task {
private:
int start;
int limit;
TLS* local_tls;
public:
Child( int s_, int l_, TLS* t_):start(s_),limit(l_),local_tls(t_){}
virtual ~Child(){
local_tls=0;
}
tbb::task* execute(){
TLS::reference local_vector = local_tls->local();
for(int i=start; i<limit;++i){
local_vector.push_back( i );
}
}
return 0;
}
};
class Cont: public tbb::task {
private:
TLS global_tls;
public:
Cont(){}
virtual ~Cont(){}
TLS* GetTls(void) { return &global_tls; }
tbb::task* execute(){
TLS::const_iterator it( global_tls.begin() );
const TLS::const_iterator end( global_tls.end() );
std::cout << "ETS.SIZE: " << global_tls.size() << std::endl;
while( it != end ) {
std::cout << "*ITSIZE: " << (*it).size() << "\n";
for( unsigned int j(0); j < (*it).size(); ++j ) {
std::cout << (*it)[j] << " " << std::endl;
}
++it;
}
return 0;
}
};
class Root: public tbb::task {
private:
public:
Root(){}
virtual ~Root(){}
tbb::task* execute(){
tbb::task_list l;
Cont& c = *new ( allocate_continuation() ) Cont();
l.push_back( (*new ( c.allocate_child() ) Child(0,10,c.GetTls()) ) );
l.push_back( (*new ( c.allocate_child() ) Child(11,21,c.GetTls()) ) );
c.set_ref_count( 2 );
c.spawn( l );
return 0;
}
};
int main(void) {
Root& r = *new(tbb::task::allocate_root()) Root( );
tbb::task::spawn_root_and_wait( r );
return 0;
}但输出结果令人尴尬。有时是:
ETS.SIZE: 2
*ITSIZE: 10
0 1 2 3 4 5 6 7 8 9
*ITSIZE: 10
11 12 13 14 15 16 17 18 19 20有时是这样的:
ETS.SIZE: 1
*ITSIZE: 20
0 1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20为什么会发生这种变化?另外,在TBB论坛上我读到,有时TLS并不包含所有的期望值,但原因显然是关于父任务和子任务的关系。不过,我不太理解这一点。
有什么帮助吗?
谢谢。
发布于 2012-04-16 18:16:11
你看到的“尴尬”的输出差异与enumerable_thread_specific无关。这只是因为Child任务由两个不同的线程(在案例1中)或相同的线程(在案例2中)执行。
https://stackoverflow.com/questions/10164598
复制相似问题