我的代码有rw_sempaphore
,只需调用我的函数unlock()
即可解锁。但是,当我的代码被调用时,它不知道它当前是否具有读或写锁。因此,它不知道是否应该拨打up_write()
或up_read()
。
我可以一个接一个地打电话,没有任何负面影响吗?有没有办法判断当前线程是否有读或写锁?
我尝试拨打downgrade_write()
然后up_read()
,但这似乎也没有用。降级读锁是不是很糟糕?
答案 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()
。
不是最漂亮的,但它确实有效。