为什么读/写锁需要锁?

时间:2012-06-22 13:00:11

标签: c linux multithreading pthreads

我有一个读/写锁的实现,如下所示。请注意,在函数的开头,有一个pthread_mutex_lock调用。如果它一次使用pthread_mutex_lock,那么使用读/写锁的好处是什么。如何仅仅使用pthread_mutex_lock

更好
int pthread_rwlock_rlock_np(pthread_rwlock_t *rwlock)
{
    pthread_mutex_lock(&(rwlock->mutex));
    rwlock->r_waiting++;
    while (rwlock->r_wait > 0)
    {
        pthread_cond_wait(&(rwlock->r_ok), &(rwlock->mutex));
    }
    rwlock->reading++;
    rwlock->r_waiting--;
    pthread_mutex_unlock(&(rwlock->mutex));
    return 0;
}

int pthread_rwlock_wlock_np(pthread_rwlock_t *rwlock)
{
    pthread_mutex_lock(&(rwlock->mutex));
    if(pthread_mutex_trylock(&(rwlock->w_lock)) == 0)
    {
        rwlock->r_wait = 1;
        rwlock->w_waiting++;
        while (rwlock->reading > 0)
        {
            pthread_cond_wait(&(rwlock->w_ok), &(rwlock->mutex));
        }
        rwlock->w_waiting--;
        pthread_mutex_unlock(&(rwlock->mutex));
        return 0;
    }
    else
    {
        rwlock->wu_waiting++;
        while (pthread_mutex_trylock(&(rwlock->w_lock)) != 0)
        {
            pthread_cond_wait(&(rwlock->w_unlock), &(rwlock->mutex));
        }
        rwlock->wu_waiting--;
        rwlock->r_wait = 1;
        rwlock->w_waiting++;
        while (rwlock->reading > 0)
        {
            pthread_cond_wait(&(rwlock->w_ok), &(rwlock->mutex));
        }
        rwlock->w_waiting--;
        pthread_mutex_unlock(&(rwlock->mutex));
        return 0;
    }
}

4 个答案:

答案 0 :(得分:4)

rwlock->mutex互斥锁用于保护rwlock结构本身的状态,而不是目标程序中读取器/写入器锁可能保护的状态。此互斥锁仅在获取或释放锁定期间保留。它只是简单地进入,以避免破坏读取器/写入器锁本身的“簿记”所需的状态。相反,读取器/写入器锁定可以通过调用者在锁定保护的结构上执行实际读取和写入来保持延长的时间段。

答案 1 :(得分:2)

在这两个函数中,rwlock->mutex在返回之前被释放。这意味着仅仅因为你持有rwlock作为读者或作者,并不意味着你持有互斥锁。

rwlock的一半是多个阅读器可以同时运行,因此这比使用互斥锁更具优势。这些读者只是简单地持有互斥锁,以获取读者锁定。他们在做实际工作时不会持有互斥锁。

答案 2 :(得分:0)

它允许多次读取或一次一次写入,这比一次读取或一次写入操作要好。

答案 3 :(得分:0)

  

如何仅仅使用pthread_mutex_lock更好?

  1. 即使使用此实现,读者也会在关键部分同时运行。
  2. 可能有一个更好(不太便携)的实现会在“快速路径”中使用原子(在等待时仍然需要锁定)。