Моя программа блокируется, и я понятия не имею, почему, учитывая, что она не будет этого делать, когда я запускаю ее в отладчике, поэтому мой первый подозрение — мой 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();
}
std::shared_timed_mutex
существует до C ++ 17: в C ++ 14.
Используйте вместо этого, он будет иметь меньше ошибок и будет почти наверняка быстрее.
C ++ 17 вводит shared_mutex
что может быть еще быстрее. Но я сильно сомневаюсь в вашей способности реализовать более быстрый общий доступ, чем shared_timed_mutex
используя стандартные примитивы C ++.
Хорошо выглядит за исключением двух проблем в этом коде:
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();
}
Это на самом деле немного проще, что приятно.