0

私のプログラムはデッドロックしています。なぜなら、デバッガーで実行しても動かないことを考えると、私の最初の疑いは私のrwLockです。標準ライブラリのみを使用したかったので、独自のバージョンを作成しました- -rwLock は C++17 まで含まれていないと思います。これは私が通常行うようなことではありません。

class RwLock
{
    std::mutex mutex;
    std::unique_lock<std::mutex> unique_lock;
    std::condition_variable condition;

    int  reading_threads;
    bool writing_threads;

public:
    RwLock();
    ~RwLock();

    void read_lock();
    void read_unlock();

    void write_lock();
    void write_unlock();
};


RwLock::RwLock() :
    mutex(),
    unique_lock(mutex, std::defer_lock),
    condition(),
    reading_threads(0),
    writing_threads(false)
{
}

RwLock::~RwLock()
{
    //TODO: find something smarter to do here.
    write_lock();
}

void RwLock::read_lock()
{
    unique_lock.lock();

    while(writing_threads)
    {
        condition.wait(unique_lock);
    }

    ++reading_threads;
    unique_lock.unlock();
}

void RwLock::read_unlock()
{
    unique_lock.lock();

    if(--reading_threads == 0)
    {
        condition.notify_all();
    }

    unique_lock.unlock();
}

void RwLock::write_lock()
{
    unique_lock.lock();

    while(writing_threads)
    {
        condition.wait(unique_lock);
    }

    writing_threads = 1;

    while(reading_threads)
    {
        condition.notify_all();
    }

    unique_lock.unlock();
}

void RwLock::write_unlock()
{
    unique_lock.lock();
    writing_threads = 0;
    condition.notify_all();
    unique_lock.unlock();
}
4

2 に答える 2

0

このコードの 2 つの問題を除けば、良さそうです。

void RwLock::write_lock()
{
    unique_lock.lock();

    while(writing_threads)
    {
        condition.wait(unique_lock);
    }

    writing_threads = 1;

    while(reading_threads)
    {
        condition.notify_all();
    }

    unique_lock.unlock();
}

まず、インクリメントwriting_threadsが遅すぎます。読者が忍び込む可能性があります。これを気にしない、または望んでいない可能性もありますが、通常、これは望ましくありません。

次に、最後のwhileループでの通知はwait. まとめると、次のようになります。

void RwLock::write_lock()
{
    unique_lock.lock();

    ++writing_threads;

    while((writing_threads > 1) || (reading_threads > 0))
    {
        condition.wait(unique_lock);
    }

    unique_lock.unlock();
}

void RwLock::write_unlock()
{
    unique_lock.lock();
    --writing_threads; // note change here
    condition.notify_all();
    unique_lock.unlock();
}

これは実際にはもう少し単純で、これは素晴らしいことです。

于 2016-11-12T20:57:37.883 に答える
0

std::shared_timed_mutexC++17 より前に存在: C++14 内。

代わりに使用してください。バグが少なくなり、ほぼ確実に高速になります。

C++17 ではshared_mutex、さらに高速になる機能が導入されています。shared_timed_mutexしかし、 C++ 標準プリミティブを使用するよりも高速な共有 rwlock を実装するあなたの能力を強く疑っています。

于 2016-11-12T20:51:12.137 に答える