2016-11-08 20 views
1

のプライベートメンバーとして使用する私はプライベートメンバーとしてboost :: mutexを含むクラスを持っています。関数が終了すると、パブリック関数の1つを呼び出してロックを解除するとロックされます。これは、オブジェクトの内部への同期アクセスを提供するためです。boost :: mutexをクラス

class StringDeque 
{ 
    boost::mutex mtx; 
    std::deque<string> string_deque; 
public: 
    StringDeque() { } 

    void addToDeque(const string& str_to_add) 
    { 
    boost::lock_guard<boost::mutex> guard(mtx); 
    string_deque.push(str_to_add); 
    } 

    string popFromDeque() 
    { 
    boost::lock_guard<boost::mutex> guard(mtx); 
    string popped_string = string_deque.front(); 
    string_deque.pop(); 
    return popped_string; 
    } 
}; 

このクラスは、特に有用であることを意図するものではないんだけど、ミューテックスやスレッドで遊んでいます。

main()には、クラスの文字列をポップしてスレッドに出力する別の関数が定義されています。これを10回繰り返してから、関数から復帰します。もう一度、これは純粋にテスト目的のためです。これは次のようになります:

void printTheStrings(StringDeque& str_deque) 
{ 
    int i = 0; 
    while(i < 10) 
    { 
     string popped_string = str_deque.popFromDeque(); 
     if(popped_string.empty()) 
     { 
     sleep(1); 
     continue; 
     } 
     cout << popped_string << endl; 
     ++i; 
    } 
} 

int main() 
{ 
    StringDeque str_deque; 
    boost::thread the_thread(printTheStrings, str_deque); 
    str_deque.addToDeque("Say your prayers"); 
    str_deque.addToDeque("Little One"); 
    str_deque.addToDeque("And Don't forget My Son"); 
    str_deque.addToDeque("To include everyone"); 
    str_deque.addToDeque("I tuck you in"); 
    str_deque.addToDeque("Warm within"); 
    str_deque.addToDeque("Keep you free from sin"); 
    str_deque.addToDeque("Until the sandman he comes"); 
    str_deque.addToDeque("Sleep with one eye open"); 
    str_deque.addToDeque("Gripping your pillow tight"); 
    the_thread.join(); 
} 

私が得続けるエラーは、boost :: mutexはコピー不可能です。 printTheStrings()関数は参照を取るので、なぜオブジェクトをコピーしようとしているのか少し混乱します。

これについて少し読んだことがあります。読み続ける1つの解決策は、boost :: mutexをオブジェクトの静的なプライベートメンバーにすることです。しかし、これはクラス変数ではなくオブジェクトごとにしたいので、これは私のmutexの目的を破ります。

これはミューテックスの悪い使用ですか?私はこのアプリケーション全体を考え直すべきでしょうか?

編集:私はちょうど両端キューからポップし、それを印刷するために目を覚ます前に両端キュー内の実際に何かがあるまでスレッドの待機を持っている多くの方に私の目的を果たすべきcondition_variable発見

。私が見ているすべての例は、これらのmutexesとcondition_variableオブジェクトをグローバルスコープで定義しています。これは非常に...オブジェクト指向ではないようです。 Boostからまっすぐな例でさえ、それがこのように行われることを示しています。これは他の人がこれらのオブジェクトを実際にどのように使用しているかです。

+1

あなたのクラスをコピー不可能にしてください。 'delete'コピーコンストラクタと代入演算子です。 –

+1

コンパイラのメッセージを書き直したり、行番号を含めて編集前のものをコピーして貼り付けたりしないでください。 tgeソース内に問題のある行を示します。 –

+0

ミューテックスをコピーしない独自のコピーコンストラクタを定義します。 http://www.boost.org/doc/libs/1_61_0/doc/html/thread/thread_management.html#thread.thread_management.thread.callable_constructor –

答えて

2

printToStringは、参考のためにStringQueueを取ります。あなたの問題は、boost::threadが引数で値をとることです。あなたが物事を変更する必要があります参照で引数を取るようにそれを強制するには:さておき、以降C++ 11からのよう

boost::thread the_thread(printTheStrings, boost::ref(str_deque)); 

、スレッドは、標準ライブラリの一部です。あなたはおそらく使用するべきですstd::thread instead

+0

私はC++ 11をサポートしている古代のコンパイラを実験的な形式で使用しています。 –

+0

ブーストを使用する理由としては、 – doron