2

複数のスレッド ( std::async) が を介して次のクラスのインスタンスを共有している場合shared_ptr、コードのこの部分でセグメンテーション違反が発生する可能性はありますか? 私の理解std::mutexが正しければ、mutex.lock()他のすべてのスレッドが呼び出されるmutex.lock()までブロックを呼び出そうとmutex.unlock()するため、ベクトルへのアクセスは純粋に順番に行われるはずです。ここで何か不足していますか?そうでない場合、そのようなクラスを設計するより良い方法はありますか (おそらく を使用std::atomic_flag)?

#include <mutex>
#include <vector>
class Foo
{
   private:
      std::mutex mutex;
      std::vector<int> values;
   public:
      Foo();
      void add(const int);
      int get();
};
Foo::Foo() : mutex(), values() {}
void Foo::add(const int value)
{
   mutex.lock();
   values.push_back(value);
   mutex.unlock();
}
int Foo::get()
{
   mutex.lock();
   int value;
   if ( values.size() > 0 )
   {
      value = values.back();
      values.pop_back();
   }
   else
   {
      value = 0;
   }
   mutex.unlock();
   return value;
}

免責事項: デフォルト値の 0 inget()は、コードの残りの部分で特別な意味を持つことを意図しています。

更新: 上記のコードは、もちろんタイプミス push_Back を除いて、私が使用するものとまったく同じです。

4

2 に答える 2

2

RAII を使用してロックを取得せず、size() > 0代わりに を使用する以外は!empty()、コードは正常に見えます。これはまさにミューテックスの使用方法であり、ミューテックスが必要な方法と場所の典型的な例です。

Andy Prowl が指摘したように、インスタンスはコピー構築またはコピー割り当てできません。

于 2013-02-12T13:53:44.920 に答える
1

これが「改善された」バージョンです。

#include <mutex>
#include <vector>
class Foo {
   private:
      std::mutex mutex;
      typedef std::lock_guard<std::mutex> lock;
      std::vector<int> values;
   public:
      Foo();
      void add(int);
      int get();
};
Foo::Foo() : mutex(), values() {}
void Foo::add(int value) {
   lock _(mutex);
   values.push_back(value);
}
int Foo::get() {
   lock _(mutex);
   int value = 0;
   if ( !values.empty() )
   {
      value = values.back();
      values.pop_back();
   }
   return value;
}

mutexなどを取得するためのRAII付き。

于 2013-02-12T15:08:20.863 に答える