1

Mir プロジェクトのソース コードを読んでいて、このコードに出くわしました。

void mir::frontend::ResourceCache::free_resource(google::protobuf::Message* key)
{
    std::shared_ptr<void> value;
    {
        std::lock_guard<std::mutex> lock(guard);

        auto const& p = resources.find(key);

        if (p != resources.end())
        {
            value = p->second;
        }

        resources.erase(key);
    }
}

これは他のプロジェクトでも見たことがあります。ブロックが lock_guard によって保護されている場合でも、消去前のマップ内の値への参照を保持します。std::shared_ptr valueを使用して値への参照を保持する理由がわかりません。

値 = p->secondを削除すると、どのような影響がありますか?

誰かが私を啓発してくれますか?

これはコードhttp://bazaar.launchpad.net/~mir-team/mir/trunk/view/head:/src/frontend/resource_cache.cppです

4

2 に答える 2

3

valueこれは、ロックされたコード内でデストラクタが実行されるのを避けるために行われていると思います。このロックは、マップの変更を保護するためのものであり、ロックされた別のオブジェクトのデストラクタなど、任意のコードを実行する必要はありません。

のデストラクタがvalue、何らかの理由でマップまたは別のスレッド共有構造に間接的にアクセスすることを想像してみてください。デッドロックに陥る可能性があります。

肝心なのは、ロックされたコードからできるだけ少ないコードを実行することです。また、ロックされたコードから外部の未知の関数 ( shared_ptrdeleter やコールバックなど) を呼び出さないでください。

于 2013-03-11T16:59:59.403 に答える
2

shared_ptr目標は、ロックが解除されるまで、デリータの実際の実行を移動することです。このようにして、デリータ (またはデフォルトのデリータを使用するデストラクタ) に長い時間がかかる場合、その操作に対してロックが保持されません。

を削除するvalue = p->secondと、ロックが保持されている間に値が破棄されます。ロックはマップを保護しますが、実際の値は保護しないため、必要以上に長くロックを保持することになります。

于 2013-03-11T17:00:20.413 に答える