【发布时间】:2011-12-21 22:37:10
【问题描述】:
我目前正在努力解决读写器问题(请参阅here)。
我在 Qt 扩展坞中找到了this 解决方案,该解决方案通过使用信号量和互斥量来保证读取器和写入器线程的公平处理。基本代码是这样的:
sem_t semaphore_;
pthread_mutex_t lock_;
void PalindromeDatabase::initializeLocks()
{
sem_init(&semaphore_, 0, NumberOfReaders_);
pthread_mutex_init(&lock_, nullptr);
}
void PalindromeDatabase::lockReaders()
{
sem_wait(&semaphore_);
}
void PalindromeDatabase::unlockReaders()
{
sem_post(&semaphore_);
}
void PalindromeDatabase::lockWriters()
{
pthread_mutex_lock(&lock_);
{
for (int i = 0; i < NumberOfReaders_; ++i)
sem_wait(&semaphore_);
}
pthread_mutex_unlock(&lock_);
}
void PalindromeDatabase::unlockWriters()
{
for (int i = 0; i < NumberOfReaders_; ++i)
sem_post(&semaphore_);
}
这似乎是一个非常优雅的解决方案。它似乎比this SO 答案中详述的pthread_rwlock_*behavior 更简单、更有效。
我想知道下面的这段代码是否是对 Qt 解决方案的正确调整,以偏爱 Reader 线程。
int readersActive_;
sem_t semaphore_;
pthread_mutex_t lock_;
pthread_mutex_t readLock_;
pthread_cond_t wait_;
void PalindromeDatabase::initializeLocks()
{
sem_init(&semaphore_, 0, numberOfReaders_);
pthread_mutex_init(&lock_, nullptr);
pthread_mutex_init(&readLock_, nullptr);
pthread_cond_init(&wait_, nullptr);
}
void PalindromeDatabase::lockReaders()
{
pthread_mutex_lock(&lock_);
{
pthread_mutex_lock(&readLock_);
sem_wait(&semaphore_);
pthread_mutex_unlock(&readLock_);
++readersActive_;
}
pthread_mutex_unlock(&lock_);
}
void PalindromeDatabase::lockReaders()
{
pthread_mutex_lock(&lock_);
{
pthread_mutex_lock(&readLock_);
sem_wait(&semaphore_);
pthread_mutex_unlock(&readLock_);
++readersActive_;
}
pthread_mutex_unlock(&lock_);
}
void PalindromeDatabase::unlockReaders()
{
sem_post(&semaphore_);
pthread_mutex_lock(&lock_);
{
--readersActive_;
if (readersActive_ == 0)
pthread_cond_signal(&wait_);
}
pthread_mutex_unlock(&lock_);
}
void PalindromeDatabase::lockWriters()
{
pthread_mutex_lock(&lock_);
{
if (readersActive_ != 0)
{
do
{
pthread_cond_wait(&wait_, &lock_);
} while (readersActive_ != 0);
}
pthread_mutex_lock(&readLock_);
for (int i = 0; i < numberOfReaders_; ++i)
sem_wait(&semaphore_);
pthread_mutex_unlock(&readLock_);
}
pthread_mutex_unlock(&lock_);
}
void PalindromeDatabase::unlockWriters()
{
for (int i = 0; i < numberOfReaders_; ++i)
sem_post(&semaphore_);
}
【问题讨论】:
-
不喜欢读取线程:这会导致写入线程永远不会写入,并且会使读取线程读取过期数据。
-
@stefaanv:是的,据我了解,大多数实现更喜欢编写器,因为它们很少见,而且写操作通常更重要。为了我自己的理解,我正在尝试实现所有三种变体(读取、写入、无偏好)。不过感谢您的提醒。
标签: c++ multithreading posix readerwriterlock