使用读或写锁定来锁定rw_semaphore

时间:2013-03-07 14:48:08

标签: linux-kernel synchronization semaphore

我的代码有rw_sempaphore,只需调用我的函数unlock()即可解锁。但是,当我的代码被调用时,它不知道它当前是否具有读或写锁。因此,它不知道是否应该拨打up_write()up_read()

我可以一个接一个地打电话,没有任何负面影响吗?有没有办法判断当前线程是否有读或写锁?

我尝试拨打downgrade_write()然后up_read(),但这似乎也没有用。降级读锁是不是很糟糕?

2 个答案:

答案 0 :(得分:1)

  

我可以一个接一个地打电话,没有任何负面影响吗?

当然不是!想象一下:

thread A                    thread B:

down_write
                            down_read (blocked)
...
unlock
|\ up_write
|                           (released, acquired read lock)
| ...
 \ up_read (lock messed up)

我从未使用rw_semaphore,但如果它是单作者多读者锁,那么这就是你的解决方案。

编辑:请注意,这需要锁定是递归的。在rw_semaphore的情况下,事实证明它确实递归。

如果我们能够检测到锁是否处于读取或写入模式(假设您已经知道 已锁定在其中一种模式中,即它已被锁定),则问题很容易解决。没有解锁)。

由于锁是多读者,我们可以使用read-try-lock来了解情况:

if (down_read_trylock(sem))
    /* semaphore was locked in read mode */
else
    /* semaphore was locked in write mode */

if情况下,信号量已经锁定在读取模式,我们再次将其锁定,因此需要两个 up_read。在else的情况下,信号量被锁定在写入模式中,因此我们需要一个up_write。这假定down_read_trylock由于达到最大读锁数或任何其他原因而失败,除了在写模式下锁被锁定。

总之:

void unlock(struct rw_semaphore *sem)
{
    if (down_read_trylock(sem))
    {
        up_read(sem);
        up_read(sem);
    }
    else
        up_write(sem);
}

注意:使用前测试!

答案 1 :(得分:1)

我最终存储了使用down_write()的进程的PID。 unlock()函数检查PID是否匹配,如果匹配则up_write()。否则,它会up_read()

不是最漂亮的,但它确实有效。