我理解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
进行检查,如果{{} 1}}失败,它只是一直返回CreateThread()
。使用pthreads,没有办法保持这种简洁明了的方法吗?
答案 0 :(得分:7)
pthread_t
是一个C类型,所以它必须有一个普通的默认构造函数;所以你可以对它进行初始化:
: thread(), // ...
您对threadValid
的使用似乎有些困惑。最好将bool
初始设置为false
,然后仅在true
成功后将其设置为pthread_create
。
答案 1 :(得分:4)
但这意味着我应该将此返回值与pthread_t一起保留并使用它来检查线程的有效性吗?
是的,或者更简单地保留一个布尔值,就像已经提到的那样。
在这种情况下,我应该如何在类构造函数中初始化这个值?
不要初始化它,在C ++中初始化成员不是强制性的。
答案 2 :(得分:2)
不幸的是,您只能使用保护变量来了解其值是否有意义。 因此,例如,您不能使用0,因为它在某些系统(例如DG / UX)上将是有效的pthread_t。 您应该使用其他东西来知道是否可以使用该值,并且您应该对其进行值初始化。
如果您可以在可移植性方面做出妥协(例如非生产代码),请考虑在Linux和Android上pthread_t应该类似于int类型,而在Darwin上它应该是一个句柄,因此如果将其初始化为0,它将起作用
答案 3 :(得分: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);
}
不要开始你的帖子in the constructor。