2

我的代码有一个rw_sempaphore可以通过一次调用我的函数来解锁unlock()。但是,当我的代码被调用时,它不知道它当前是否具有读锁或写锁。所以它不知道它是否应该调用up_write()or up_read()

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

我试着打电话downgrade_write(),然后up_read(),但这似乎也不起作用。降级读锁不好吗?

4

2 回答 2

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_reads。在 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);
}

注意:使用前请测试!

于 2013-03-07T15:03:00.047 回答
1

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

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

于 2013-03-08T14:08:35.573 回答