gpt4 book ai didi

c++ - 使用信号量的读写器偏好

转载 作者:行者123 更新时间:2023-11-30 04:30:40 30 4
gpt4 key购买 nike

我目前正在研究读写器问题的正确实现(请参阅 here)。

我找到了 this Qt 码头中的解决方案通过使用信号量和互斥量保证公平对待 Reader 和 Writer 线程。基本代码是这样的:

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 中详述的 pthread_rwlock_* 行为相比,它似乎更容易、更有效。所以回答。

我想知道下面这段代码是否是对 Qt 解决方案的正确调整以更喜欢阅读器线程。

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

最佳答案

你的代码有很多问题:

  1. 信号量仅供作者使用,因此没有意义。
  2. 在为 writer 锁定时,您使用互斥锁,而在解锁时则不用。
  3. 当#readers 变为零时,readers 发出条件变化的信号,writer 等待条件变量的信号,但不检查条件。
  4. 在为 writer 锁定时,如果 #readers 已经为零,它实际上不会锁定。

考虑到我所说的这很容易,锁定仍然很棘手,我想了想,我希望我用这个伪代码破解它,关注正确的顺序而不是正确的符号:

void lockReader()
{
lock(rdmutex); // make sure Reader and Writer can't interfere during locking
lock(wrmutex); // lock mutex so waitfor can unlock
while (writer_)
waitfor(wrcv, wrmutex); // no active writers

++readers_; // at least 1 reader present
unlock(wrmutex);
unlock(rdmutex);
}

void unlockReader()
{
lock(rdmutex);
bool noReaders = (--readers_ == 0);
unlock(rdmutex);
if (noReaders) signal(rdcv); // signal when no more readers
}

void lockWriter()
{
lock(WritersLock); // only 1 writer allowed
lock(rdmutex); // lock mutex so waitfor can unlock and no interference by lockReader
while (readers_ != 0)
waitfor(rdcv, rdmutex); // wait until no more readers
lock(wrmutex);
writer_ = true; // a writer is busy
unlock(wrmutex);
unlock(rdmutex);
// WritersLock is still locked
}

void unlockWriter()
{
lock(wrmutex);
writer_ = false;
unlock(wrmutex);
signal(wrcv); // no more writer (until WritersLock is unlocked)

unlock(WritersLock);
}

事实证明,Qt 实现更简单,但我的算法不需要提前知道最大读者数。

关于c++ - 使用信号量的读写器偏好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8587786/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com