TBB基础之初始化&终止

开始深入的TBB之旅之前,我们先看看怎么初始化和终止TBB库吧,毕竟这是使用TBB的一个基础~~~

TBB里提供了一个class:task_scheduler_init,该class会在constructor中初始化TBB,在destructor中终止TBB库。

这样我们就知道了最简单的初始化&终止TBB的方法:

 
   
1 #include " tbb/task_scheduler_init.h "
2 using namespace tbb;
3
4
int main() {
5 task_scheduler_init init;
6 ...
7 return 0 ;
8 }

 

这样,由task_scheduler_init的constructor和destructor就提供了初始化和终止的功能。

下面我们来看看task_scheduler_init的constructor是怎样的,打开header file:tbb/task_scheduler_init.h,找到它的constructor的declaration:

 
   
1 // ! Class representing reference to tbb scheduler.
2
/* * A thread must construct a task_scheduler_init, and keep it alive,
3 during the time that it uses the services of class task.
4 @ingroup task_scheduling */
5
class task_scheduler_init: internal ::no_copy {
6 /* * NULL if not currently initialized. */
7
internal ::scheduler * my_scheduler;
8 public :
9 // ! Typedef for number of threads that is automatic.
 
10 static const int automatic = - 1 ;
11
12 // ! Argument to initialize() or constructor that causes initialization to be deferred.
 
13 static const int deferred = - 2 ;
14
15 // ! Ensure that scheduler exists for this thread
 
16 /* * A value of -1 lets tbb decide on the number
17 of threads, which is typically the number of hardware threads.
18 For production code, the default value of -1 should be used,
19 particularly if the client code is mixed with third party clients
20 that might also use tbb.
21
22 The number_of_threads is ignored if any other task_scheduler_inits
23 currently exist. A thread may construct multiple task_scheduler_inits.
24 Doing so does no harm because the underlying scheduler is reference counted. */
 
25 void initialize( int number_of_threads = automatic );
26
27 // ! Inverse of method initialize.
 
28 void terminate();
29
30 // ! Shorthand for default constructor followed by call to intialize(number_of_threads).
 
31 task_scheduler_init( int number_of_threads = automatic ) : my_scheduler(NULL) {
32 initialize( number_of_threads );
33 }
34
35 // ! Destroy scheduler for this thread if thread has no other live task_scheduler_inits.
 
36 ~ task_scheduler_init() {
37 if ( my_scheduler )
38 terminate();
39 internal ::poison_pointer( my_scheduler );
40 }
41 };

 

我们看到task_scheduler_init的constructor有一个缺省参数number_of_threads,默认情况下取值为automatic(-1),它的含义是指在constructor时自动调用initialize函数,并创建出线程调度器。

number_of_threads可能的取值包括:

  • automatic(-1):constructor时自动调用initialize()函数,创建合适的线程调度器
  • deferred(-2):表示在consturctor时不要调用initialize()函数初始化,而等到后面手动初始化
  • 任意正整数:指定期望的线程数量,一般不要自己指定,除非你已经针对平台进行过特定的调节;当然我们也可以先使用deferred创建,然后在通过initialize(number_of_threads)来指定线程数量

我们来看一个典型的利用deferred参数来动态设定的例子:

 
   
1 int main( int argc, char * argv[] ) {
2 int nthread = strtol(argv[ 0 ], 0 , 0 );
3 task_scheduler_init init(task_scheduler_init::deferred);
4 if ( nthread >= 1 )
5 init.initialize(nthread);
6 // ... code that uses task scheduler only if nthread>=1 ...
7
if ( nthread >= 1 )
8 init.terminate();
9 return 0 ;
10 }

 

一个要注意的是:task_scheduler_init的构造是很费时的,不要每次使用TBB时都创建它,而是在main或者入口的地方创建一次就可以了。

 

在TBB深入部分我们会去看看task_scheduler_init是怎么实现线程调度器的~~~(待续)

你可能感兴趣的:(TBB,constructor,destructor,thread,reference,initialization,class)