我的代码有一个rw_sempaphore
可以通过一次调用我的函数来解锁unlock()
。但是,当我的代码被调用时,它不知道它当前是否具有读锁或写锁。所以它不知道它是否应该调用up_write()
or up_read()
。
我可以一个接一个地打电话而没有任何负面影响吗?有没有办法判断当前线程是否有读锁或写锁?
我试着打电话downgrade_write()
,然后up_read()
,但这似乎也不起作用。降级读锁不好吗?
我的代码有一个rw_sempaphore
可以通过一次调用我的函数来解锁unlock()
。但是,当我的代码被调用时,它不知道它当前是否具有读锁或写锁。所以它不知道它是否应该调用up_write()
or up_read()
。
我可以一个接一个地打电话而没有任何负面影响吗?有没有办法判断当前线程是否有读锁或写锁?
我试着打电话downgrade_write()
,然后up_read()
,但这似乎也不起作用。降级读锁不好吗?
我可以一个接一个地打电话而没有任何负面影响吗?
当然不是!想象一下:
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
s。在 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);
}
注意:使用前请测试!
我最终存储了使用的进程的 PID down_write()
。该unlock()
函数检查 PID 是否匹配,up_write()
如果匹配则执行。否则,它会up_read()
。
不是最漂亮的,但它有效。