1

マルチスレッド アプリケーションに存在するリソース格納オブジェクトがあります。(できれば) スレッド セーフを確保するために、リソースにアクセスしたり、新しいリソースを挿入したりするたびにミューテックスをロックします。たとえば、新しいリソースを挿入するには:

void ResourceManager::insertResource(const std::string& id)
{
    // create the object with such ID
    Resource res = Resource(id);

    // ... more code on res

    // lock the mutex to insert the resource
    std::lock_guard<std::mutex> guard(mResourcesMutex);

    // insert the resource in a STL container
    mResources.insert(ResourceContainer::value_type(id, res));

    // ... more code that does not require the mutex lock
}

そのデストラクタができるだけ早く呼び出され、他のスレッドがリソースにアクセスできるように、lock_guard のスコープを最小限に抑えたいと考えています。特に、mResources.insert(...) ステートメントの後にミューテックスのロックを解除したいと思います。

単純な if ステートメントを使用して lock_guard のスコープを設定することを考えました。

    if(true)
    {
        std::lock_guard<std::mutex> guard(mResourceMutex);
        mResources.insert(ResourceContainer::value_type(id, res);
    }

しかし、それが機能しているかどうかはわかりません。これがlock_guardを正しくスコープしているのか、それともコンパイラが私がおかしいと思ってifステートメントを取り出してコードを最適化しているのかを確認するのは難しいと思います。

私の質問は次のとおりです。

  • これは稼働していますか?
  • その価値はありますか?パフォーマンスへの影響はありますか?
  • より良い代替手段はありますか?
4

2 に答える 2

6
  • はい、動作します。スコープを終了するとすぐに、そのスコープにローカルなオブジェクトはすぐに破棄されます。

  • はい、特にあなたの例のような場合には価値があります(リソースが早期に解放されるようにオブジェクトの有効期間を短縮しますが、一時識別子のスコープを縮小し、その後アクセスできなくするためだけに使用することもできます。この使用法はあなたの例よりも少し面白くありませんが)。

  • はい、(わずかに)より良い代替手段があります。if節なしで中括弧を使用するだけです:

.

{
    std::lock_guard<std::mutex> guard(mResourceMutex);
    mResources.insert(ResourceContainer::value_type(id, res);
}

適切なコンパイラは を最適化できるif (true)ため、生成されたコードは同一になりますが、スタイルの観点からは中括弧だけがはるかにきれいになります。さらに、ブレースだけでもよく知られており、すぐに認識できるイディオムですが、 your istif (true)はそうではなく、読者に (たとえ簡単であっても) 「その if の目的は何ですか? ああ、待って、そうです、それは通常の範囲制限イディオムです。 ..」。

于 2013-04-24T09:47:35.250 に答える
5

if(true)を使用する理由 簡単に使用できますblock scope

{
    std::lock_guard<std::mutex> guard(mResourceMutex);
    mResources.insert(ResourceContainer::value_type(id, res);
}
于 2013-04-24T09:48:12.393 に答える