2016-05-14 10 views
2
#include <pthread.h> 

class C { 
private: 
    int a; 
    pthread_t id; 

    int getA() {return a;} 
    static void* threadFunction(void* arg) {((C*)arg)->getA();return 0;} 

public: 
    C() { 
     a=2; 

     pthread_create(&id,NULL,threadFunction,this); 
    } 
    ~C() {pthread_join(id,NULL);} 

}; 

int main(int argc, char** argv) { 
    C c; 
} 

上記のコードは安全な/定義された/良い方法ですか?"this"をコンストラクタで使用してスレッドを安全に開始できますか?

コンストラクタが返された後にスレッドを開始する必要がありますか?

+2

コンストラクタの 'this'は問題ではありません。問題は 'threadFunction'の' getA() '呼び出しです。まだ生存していない(そのコンストラクタがまだ返されていない)オブジェクトのメンバ関数を呼び出しています。コンストラクタ内からメンバ関数を呼び出すことはできますが、メンバ関数が依存するすべてのクラス不変条件がコール時に確立されているのはあなたの責任です。 –

+0

"メンバー関数が依存するすべてのクラス不変式"。これはクラスのメンバ変数ですか(int aなど)? –

答えて

1

コンストラクタでスレッドを開始する具体的な例は何も問題ありません。スレッドがアクセスするクラスメンバは初期化されています。それは、それがいつも「安全」であることを意味するわけではありません。

たとえば、スレッドが呼び出す仮想メソッドを持つクラスがあります。明らかに、仮想メソッドをオーバーライドする最も派生したオブジェクトが構築されるまで、スレッドが仮想メソッドを呼び出さないように適切な手順が行われない限り、それは「安全」ではなく、未定義の動作になります。

適切な手順を実行したとしても、仮想メソッドが実行する操作や実行しない操作によっては、安全であるかどうかは不明です。

このように、安全であるかどうかにかかわらず、すべての場合に適用される普遍的な答えはありません。コンストラクタから開始されるスレッドのそれぞれの特定のユースケースは、それが「安全」であるかどうかを判断するために分析される必要があります。

しかし、これはC++の他の多くの側面とはまったく変わりません。

関連する問題