我明白, 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); }
不要在构造函数中启动你的线程。