0

これが質問ではなく議論であることは承知していますが、1 つまたは複数の回答を提供できると思いますので、どうぞ。

私はそのようなクラスを持っています

class MyAwesomeObject {
public:
    std::mutex theListMutex;
    std::list<int> theList;
};

さて、意図は非常に明白であり、例は意図的に学術的なものになっていると思いますが、私の現実からそれほど離れていません. 次に、私のアプリケーションは、そのようなオブジェクトを大量に処理します。それらはすべて別の場所にあるベクトルに格納されますが、すべて問題ありません。コンパイル時に問題が発生します。私は VS2012 を使用していますが、他のコンパイラでも同様のエラーが発生する可能性があると思います。

error C2248: 'std::mutex::mutex' : cannot access private member declared in class 'std::mutex'
1>          c:\program files\microsoft visual studio 11.0\vc\include\mutex(116) : see declaration of 'std::mutex::mutex'
1>          c:\program files\microsoft visual studio 11.0\vc\include\mutex(107) : see declaration of 'std::mutex'
1>          This diagnostic occurred in the compiler generated function 'MyApp::MyAwesomeObject ::MyAwesomeObject (const MyApp::MyAwesomeObject &)'

ここでSOで他の多くの質問を行ったので、その意味は私には非常に明確です。基本的には「ミューテックスはコピーできない」と述べており、私はそれで問題ありません。したがって、これまでの私の戦略は、ミューテックスを a にして、それでshared_ptr<mutex>完了することでした。唯一の「欠点」は、ミューテックスにアクセスするときにばかげた逆参照構文を使用する必要があることです。もちろん、これはまったくばかげているわけではなく、私が使用する他のすべてのドット表記の中で少しぎこちなく、際立っています。場所。

さて、私の質問に移りましょう:共有ポインタを使用して問題を解決する正しい方法はありますか? 私が知っている限り、所有権を他の人に譲渡していないので、代わりに一意のポインターを使用した可能性があります (オブジェクトのメンバーであるポインターでメソッドを呼び出すことが実際に所有権の譲渡の形式でない限り)? ミューテックスをコピーできないという事実を回避する他の方法はありますか?

4

5 に答える 5

2

いいえ、a を使用することは、この問題に対処する正しい方法でstd::shared_ptrはありません。

オブジェクトをコピー可能にする場合は、ソースのミューテックスをロックするコピー コンストラクターを定義してから、内容をコピーします。これについて、Mike Spertus が私のブログにゲスト投稿を書きました: http://www.justsoftwaresolutions.co.uk/threading/thread-safe-copy-constructors.html

オブジェクトを移動可能にしたい場合 (Jonathan が指摘したように、オブジェクトをベクトルに格納するために必要なのはこれだけです)、上記のように移動コンストラクターを定義するか、Jonathan の使用に関する提案に従うことができますstd::unique_ptr<std::mutex>

于 2013-07-05T13:12:43.680 に答える
0

もう 1 つの可能性は、 orの代わりにdequeorを使用することです。これは、格納する型に移動可能/コピー可能の要件を課さないためです (メソッド構築を使用して要素をコンテナーに格納し、コンテナーをコピーしていないと仮定すると、コース)。listvectoremplace_*

于 2013-07-05T14:53:04.743 に答える
0

shared_ptrミューテックスの所有者が複数存在することはないため、a は必要ありません。

を使用しますstd::unique_ptr<std::mutex>。これにより、オブジェクトはコピー可能ではなく移動のみになりますが、vector. そうすれば、リストの所有権と関連するミューテックスをあるオブジェクトから別のオブジェクトに転送できますが、それらをコピーすることはできません。

つまりMyAwesomeObject、ミューテックスがない空の「移動元」状態になるため、そのリストを使用しないでください。その状態にあるかどうかを照会するメンバーを追加して、ミューテックスなしで空のオブジェクトが与えられたかどうかをユーザーが判断できるようにする必要があります。

class MyAwesomeObject {
    std::unique_ptr<std::mutex> theListMutex;
    std::list<int> theList;

public:
    bool valid() const { return (bool)theListMutex; }
};
于 2013-07-05T12:05:46.713 に答える
0

Mutex 戦略は、オブジェクトごとや this ごとではなく、「トランザクションの範囲」の概念に基づく必要があります。そのあたり。

これで、トランザクションのスコープは次のようになります

  • A:リストなどの単一の共有データ構造を操作する
  • B: 複数のリスト、カウンターなどと言う複数の共有データ構造の操作
  • C:複数の共有データ構造と共有外部[ファイル記述子、またはデータベース接続などの可能性があります]リソースの操作
于 2013-07-05T12:11:04.207 に答える