0

我的程序死锁了,我不知道为什么,因为当我在调试器中运行它时它不会这样做,所以我的第一个怀疑是我的 rwLock,我编写了自己的版本,因为我只想使用标准库 - - 我认为直到 C++17 才包含 rwLock - 这不是我通常做的事情。

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

看起来不错,除了此代码中的两个问题:

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_mutex在 C++17 之前存在:在 C++14 中。

改用它,它的错误会更少,而且几乎可以肯定会更快。

C++17 引入了shared_mutex哪个可以更快。但我强烈怀疑您实现比shared_timed_mutex使用 C++ 标准原语更快的共享 rwlock 的能力。

于 2016-11-12T20:51:12.137 回答