正确的pthread_t初始化和处理

时间:2015-06-16 12:35:57

标签: 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);
    }
};

我也理解,如果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,没有办法保持这种简洁明了的方法吗?

4 个答案:

答案 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