Что-то не так с этой реализацией rwLock?

Моя программа блокируется, и я понятия не имею, почему, учитывая, что она не будет этого делать, когда я запускаю ее в отладчике, поэтому мой первый подозрение — мой 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();
}

0

Решение

std::shared_timed_mutex существует до C ++ 17: в C ++ 14.

Используйте вместо этого, он будет иметь меньше ошибок и будет почти наверняка быстрее.

C ++ 17 вводит shared_mutex что может быть еще быстрее. Но я сильно сомневаюсь в вашей способности реализовать более быстрый общий доступ, чем shared_timed_mutex используя стандартные примитивы C ++.

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();
}

Это на самом деле немного проще, что приятно.

0

По вопросам рекламы [email protected]