正确的pthread_t初始化和处理

lor*_*ova 3 c++ linux pthreads

我理解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);
    }
};
Run Code Online (Sandbox Code Playgroud)

我也明白,如果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;
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

我有一个Windows API背景,并且有一个线程有它的HANDLE值,可以安全地初始化NULL,并且可以检查NULL,如果CreateThread()失败,它只是一致地返回NULL.使用pthreads,没有办法保持这种简洁明了的方法吗?

eca*_*mur 8

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

    : thread(), // ...
Run Code Online (Sandbox Code Playgroud)

你的用法threadValid似乎有些困惑.最好将它bool设置为初始设置false,然后仅truepthread_create成功后设置它.

  • 正如@Pet Johansson所建议的那样,我喜欢默认构造函数的这种用法,而不是初始化它,因为这样在代码审查过程中它似乎并不健忘. (2认同)

Per*_*son 5

但这意味着我应该将此返回值与 pthread_t 一起保留并使用它来检查线程有效性?

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

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

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

  • @Lorenzo,不,[`pthread_create` 在出错时返回错误代码](http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_create.html#tag_03_525_05)。但是,它确实在成功时返回零,因此您仍然可以检查非零以指示失败。 (2认同)