【问题标题】:downing a rw_semaphore with a read or write lock使用读或写锁关闭 rw_semaphore
【发布时间】:2013-03-07 14:48:07
【问题描述】:

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

我可以一个接一个地调用它们而不会产生任何负面影响吗?有没有办法判断当前线程是读锁还是写锁?

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

【问题讨论】:

    标签: linux-kernel synchronization semaphore


    【解决方案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。在其他情况下,信号量被锁定在写模式,所以我们需要一个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);
    }
    

    注意:使用前测试!

    【讨论】:

    • 这听起来不错,但我不认为rw_semaphores 可以递归。除非我误解了 lxr.free-electrons.com/source/include/linux/rwsem.h#L114 。我可以使用嵌套功能,还是不能保证它存在
    • 你是对的。似乎使用 *_nested 函数可能是可能的,但我真的不知道。一个技巧是检查信号量的count 字段。快速浏览一下,count == -1 表示写锁定,count > 0 表示读锁定。
    • 我想这会奏效。或者我想我可以使用除了rw_semaphore 之外的递归锁定机制,虽然它不会那么漂亮。
    • @zsalzbank,我记得我对普通信号量有同样的问题。我不明白为什么没有 is_read_lockedis_write_locked 函数(而 isis_locked 函数)。我怀疑这个 API 会在很长一段时间内发生变化,所以你可能可以使用 count
    • 我可能会尝试使用 count,但由于这可能不是它的预期用途,所以我现在使用写锁所有者的进程 PID 作为条件。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 2010-11-03
      • 2018-12-18
      • 1970-01-01
      相关资源
      最近更新 更多