纠正pthread_t的初始化和处理

我明白, pthread_t应该被视为一个不透明的值,但是我不知道如何初始化它作为一个类的成员,我怎样才能检查其有效性。

考虑这个代码示例:

 class MyClass { public: pthread_t thread; MyClass() : thread(0) // Wrong because pthread_t should be an opaque value, // so how should I initialize it? {} ~MyClass() { if( thread ) // Wrong, but how can I verify if it is valid? pthread_join(thread, NULL); } }; 

我也明白,如果pthread_create()失败, pthread_t值可能不一致。 所以我应该只依靠pthread_create()的返回值。 但是这意味着我应该保留这个返回值和pthread_t一起使用它来检查线程的有效性吗? 在这种情况下,我应该如何在类的构造函数中初始化这个值?

 class MyClass { public: pthread_t thread; int threadValid; MyClass() : thread(0), // Wrong because pthread_t should be an opaque value, // so how should I initialize it? , threadValid(1) // pthread_create return zero in case of success, // so I can initialize this to any nonzero value? {} ~MyClass() { if( threadValid == 0 ) // Nonzero means thread invalid. // Is this the correct approach? { pthread_join(thread, NULL); threadValid = 1; } } }; 

我有一个Windows API背景,并有一个线程有它的HANDLE值,可以安全地初始化为NULL ,并可以检查NULL ,如果CreateThread()失败,它只是始终返回NULL 。 用pthreads,没有办法保持这个简洁而又简单的方法吗?

但是这意味着我应该保留这个返回值和pthread_t一起使用它来检查线程的有效性吗?

是的,或者更简单地保持一个布尔值,就像已经提到的那样。

在这种情况下,我应该如何在类的构造函数中初始化这个值?

不要初始化它,在C ++中初始化成员不是强制性的。

pthread_t是一个C类型,所以它必须有一个简单的默认构造函数; 所以你可以重新初始化它:

  : thread(), // ... 

你使用threadValid似乎有点困惑。 最好将其设置为false ,然后只有在pthread_create成功时才将其设置为true

不幸的是,你只能使用一个守护变量来知道它的值是否合理。 因此,例如,您不能使用0,因为它在某些系统上是有效的pthread_t(例如DG / UX)。 你应该使用别的东西来知道这个值是否可以被使用,你应该重新初始化它。

如果你可以妥协的可移植性(例如非生产代码),考虑在Linux和Android pthread_t应该像一个int类型,在达尔文应该是一个句柄,所以它会工作,如果你初始化为0。

 pthread_t thread_handle; pthread_attr_t thread_attributes; pthread_attr_init(&thread_attributes); pthread_attr_setdetachstate(&thread_attributes, PTHREAD_CREATE_JOINABLE); threadValid = (::pthread_create(&thread_handle, &thread_attributes, function, data) == 0); 

当关闭它时:

 if (threadValid) { ::pthread_join(thread_handle, 0); } 

不要在构造函数中启动你的线程。