2

各スレッドは、'insert' 関数を使用して (多くても 1 回) オブジェクトをコンテナーに挿入できます。その後、スレッドは「get」関数を使用してこのオブジェクトにアクセスしようとする場合があります。したがって、同じスレッドで使用された場合、'insert' と 'get' の間に競合はありません。ただし、別のスレッドが「get」を呼び出している間に、別のスレッドが独自のオブジェクトを挿入しようとする場合があります。

この状況で同期方法を必要としないコンテナーが必要です。

スレッドの数は、実行ごとに大幅に異なる場合があります。

class Object;
class Container<Object>;

Container<Object> g_container;

void insert(int threadId)
{
    ScopedLock<Mutex> lock(insertMutex);
    Object obj;
    g_container[threadId] = obj;
}

Object get(int threadId)
{
    return g_container[threadId];
}
4

3 に答える 3

1

コンテナー ポインターのベクトルを使用できます。各スレッドは、独自のコンテナー インスタンスを管理し、それをコンテナー ポインターの配列に登録します。

template <typename T>
struct Container {
    Mutex insertMutex;
    ContainerType<T> container;
    int index;
    void insert (T &obj) {
        ScopedLock<Mutex> lock(insertMutex);
        container.insert(obj);
    }
    T get () {
        return *container.begin();
    }
    void register_container () {
        if (index != 0) return;
        if (counter == MAX_THREADS) throw 0;
        index = ++counter;
        ScopedLock<Mutex> lock(registerMutex);
        containers.push_back(this);
    }
    static std::vector<Container *> containers;
    static Atomic<int> counter;
    static Mutex registerMutex;
};

template <typename T>
std::vector<Container<T> *> Container<T>::containers;

template <typename T>
Atomic<int> Container<T>::counter;

template <typename T>
Mutex Container<T>::registerMutex;

これで、 を繰り返し処理してContainer<T>::containersすべてのコンテナーにアクセスできます。

于 2012-07-03T06:58:56.547 に答える
1

+1 ジェームス ブロック。

しかし、スレッドごとに 1 つのコンテナーが必要でありながらミューテックスが必要なように思えます。99.9% の確率で操作が最初に成功するため、ミューテックスのロック/ロック解除は安価です。しかし、「マスター」スレッドには、他のスレッドを調べている間、ときどき一時停止する機能があります。

各スレッドにオブジェクトが 1 つしかない場合、コンテナーはなくなります。オブジェクトをロックするだけです。実績のあるパフォーマンスの問題でない限り、ロックのコストについて心配する必要はありません。その場合、問題はロックを解除することではなく、単に使用頻度を減らすことです。したがって、オブジェクトをロックしたままにして、100 回ごとにロックを解除するだけにしてください。必要に応じて条件変数と組み合わせます。

于 2012-07-03T07:46:25.183 に答える
1

あなたが探しているものは、通常「ロックのないデータ構造」と呼ばれます。

ロックフリーのコンテナが必要だと思う理由は理解できますが、そうではないことはほぼ約束できます。彼らは通常、価値があるよりも多くの問題を抱えています。通常のコンテナーへのすべてのアクセスを管理するミューテックスを 1 つだけ持つ必要があります。コンテナーに挿入するミューテックスをロックします。コンテナーから削除するミューテックスをロックします。そして、コンテナーを読み取る (または反復処理する) 前にミューテックスをロックします。

以下は、C++ 標準委員会の議長である Herb Sutter による有益な議論です。

http://www.drdobbs.com/cpp/lock-free-code-a-false-sense-of-security/210600279

于 2012-07-03T07:21:40.277 に答える