2017-09-19 80 views
0

"std :: mutex my_mutex"をプライベートメンバ変数として持つクラスを定義しました。しかし、私は別のスレッドから呼び出されるメンバ関数でlock_guardを使ってそれを使用しようとすると、コンパイラは多くのエラーをスローします。このミューテックスをクラスの外に保つと、それは機能します。コードは次のようになります。クラス内のメンバ変数としてmutexを使用

class ThreadClass 
{ 
    std::mutex my_mutex; 
    public: 
    void addToList(int max, int interval) 
    { 

     std::lock_guard<std::mutex> guard(my_mutex); 
     for (int i = 0; i < max; i++) 
     { 
      // Some operation 
     } 
    } 
}; 


int main() 
{ 
    std::thread ct(&ThreadClass::addToList,ThreadClass(),100,1); 
    std::thread ct2(&ThreadClass::addToList,ThreadClass(),100,10); 
    std::thread ct3(&ThreadClass::print,ThreadClass()); 

    ct.join(); 
    ct2.join(); 
    ct3.join(); 
    } 

同じmy_mutexがクラスの外に保持されている場合は、正常に動作します。したがって、同じ変数がクラス内にあり、スレッドによって動作するメンバ関数内で呼び出されたとき、それは静的メンバのように扱われますか?

+0

あなたがスレッドにパラメータとして一時オブジェクトを渡してみてくださいなぜ? –

答えて

4

std::threadコンストラクタは、実行された関数に渡される引数をコピーします。しかし、std::mutexはコピー不可能なので、ThreadClassはそのようなメンバーを持っていればコピーできません。

一時的なThreadClassオブジェクトをstd::threadに渡していますが、おそらくすべてのスレッドで同じオブジェクトを使用したいと思うかもしれません。 std::refを使用すると、既存のオブジェクトの参照を渡すことができます。次のコードはGCC 7.1.0でコンパイルされます。

#include <thread> 
#include <mutex> 

class ThreadClass 
{ 
    std::mutex my_mutex; 
public: 
    void addToList(int max, int interval) 
    { 
     std::lock_guard<std::mutex> guard(my_mutex); 
     // ... 
    } 
    void print() 
    { 
     // ... 
    } 
}; 

int main() 
{ 
    ThreadClass obj; 
    std::thread ct(&ThreadClass::addToList, std::ref(obj), 100, 1); 
    std::thread ct2(&ThreadClass::addToList, std::ref(obj), 100, 10); 
    std::thread ct3(&ThreadClass::print, std::ref(obj)); 

    ct.join(); 
    ct2.join(); 
    ct3.join(); 
} 

代わりに参照のオブジェクトへのポインタを渡すでも動作するはずです:

std::thread ct(&ThreadClass::addToList, &obj, 100, 1); 
+0

は、作業したオブジェクトへのポインタを渡します。しかし、addToListへのstd :: ref(obj)はパラメータ化されたメンバ関数では機能しませんでした。 – Prat

関連する問題