正确 pthread_t 初始化和处理
Correct pthread_t initialization and handling
我知道 pthread_t
应该被视为一个不透明的值,但是我不知道在用作 class 成员时如何初始化它,以及如何检查它的有效性.
考虑此代码示例:
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()
的 return 值。但这意味着我应该将此 returned 值与 pthread_t
一起保留并使用它来检查线程有效性?在这种情况下,我应该如何在 class 构造函数中初始化这个值?
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()
失败,它只会一直 returns NULL
。使用 pthreads 就没有办法保持这种简洁明了的方法吗?
pthread_t
是 C 类型,所以它必须有一个平凡的默认构造函数;所以你可以对它进行值初始化:
: thread(), // ...
您对 threadValid
的用法似乎有些混乱。最好将其设置为 bool
,最初设置为 false
,然后在 pthread_create
成功后才将其设置为 true
。
不幸的是,您只能使用保护变量来了解其值是否有意义。
因此,例如您不能使用 0,因为它在某些系统上是有效的 pthread_t(例如 DG/UX)。
您应该必须使用其他东西来知道该值是否可以使用,并且您应该对其进行值初始化。
如果您可以在可移植性(例如非生产代码)上做出妥协,请考虑 Linux 和 Android pthread_t 应该像一个 int 类型,而在 Darwin 上它应该是一个句柄,所以如果你将它初始化为 0,它就会工作。
But this means that I should keep this returned value along with pthread_t and use it to check thread validity?
是的,或者更简单地保留一个布尔值,就像已经提到的那样。
And in this case, how should I initialize in the class constructor this value?
不要初始化,在C++中不强制初始化成员。
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。
我知道 pthread_t
应该被视为一个不透明的值,但是我不知道在用作 class 成员时如何初始化它,以及如何检查它的有效性.
考虑此代码示例:
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()
的 return 值。但这意味着我应该将此 returned 值与 pthread_t
一起保留并使用它来检查线程有效性?在这种情况下,我应该如何在 class 构造函数中初始化这个值?
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()
失败,它只会一直 returns NULL
。使用 pthreads 就没有办法保持这种简洁明了的方法吗?
pthread_t
是 C 类型,所以它必须有一个平凡的默认构造函数;所以你可以对它进行值初始化:
: thread(), // ...
您对 threadValid
的用法似乎有些混乱。最好将其设置为 bool
,最初设置为 false
,然后在 pthread_create
成功后才将其设置为 true
。
不幸的是,您只能使用保护变量来了解其值是否有意义。 因此,例如您不能使用 0,因为它在某些系统上是有效的 pthread_t(例如 DG/UX)。 您应该必须使用其他东西来知道该值是否可以使用,并且您应该对其进行值初始化。
如果您可以在可移植性(例如非生产代码)上做出妥协,请考虑 Linux 和 Android pthread_t 应该像一个 int 类型,而在 Darwin 上它应该是一个句柄,所以如果你将它初始化为 0,它就会工作。
But this means that I should keep this returned value along with pthread_t and use it to check thread validity?
是的,或者更简单地保留一个布尔值,就像已经提到的那样。
And in this case, how should I initialize in the class constructor this value?
不要初始化,在C++中不强制初始化成员。
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。