【问题标题】:Is there a cross platform version of window vista's slim reader writer locks?windows vista的slim reader writer locks有跨平台版本吗?
【发布时间】:2009-12-08 08:04:23
【问题描述】:

我完全被 Windows SRW 实现的质量所震撼。它比关键部分更快,并且只有几个字节的内存开销。

不幸的是,它只有 Windows Vista/Windows 7。

由于这是一个纯用户土地实现,有人知道它是否有跨平台实现吗?有没有人对那里的解决方案进行逆向工程?

我不想添加诸如 boost 之类的东西只是为了引入不到 100 LOC 的解决方案。

【问题讨论】:

    标签: c windows multithreading


    【解决方案1】:

    如果您想要符合某些标准的“便携”...如果您使用的是 POSIX 线程,则有 @987654321@ 和朋友。当然,这些通常不用于 Windows,而是用于 Unix 类型的操作系统。

    但是,如果您的意思是“可移植到 Windows 的多个版本......”的意义上的“可移植”,ntdll 中有一些未记录的调用实现了 RW 锁。 RtlAcquireResourceShared()RtlAcquireResourceExclusive()

    这是来自WINE's implementation的一些原型:

    void WINAPI RtlInitializeResource(LPRTL_RWLOCK rwl);
    void WINAPI RtlDeleteResource(LPRTL_RWLOCK rwl);
    BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK rwl, BYTE fWait);
    BYTE WINAPI RtlAcquireResourceShared(LPRTL_RWLOCK rwl, BYTE fWait);
    void WINAPI RtlReleaseResource(LPRTL_RWLOCK rwl);
    

    请注意,您可能必须自己从ntdll.dll@987654323@ 这些。

    至于引用的结构...这是 WINE 声明的内容:

    typedef struct _RTL_RWLOCK {
       RTL_CRITICAL_SECTION rtlCS;
    
       HANDLE hSharedReleaseSemaphore;
       UINT   uSharedWaiters;
    
       HANDLE hExclusiveReleaseSemaphore;
       UINT   uExclusiveWaiters;
    
       INT    iNumberActive;
       HANDLE hOwningThreadId;
       DWORD  dwTimeoutBoost;
       PVOID  pDebugInfo;
    } RTL_RWLOCK, *LPRTL_RWLOCK;
    

    如果您不想使用 pthread 并且不想链接到粗略的未记录功能...您可以查找 rwlock 实现并根据其他操作自行实现...说@987654324@ ,或者可能是更高级别的原语,例如信号量和事件。

    【讨论】:

    • 好吧,我不想要系统调用,这不是 SRW 的代码。他们很快。我想要的只是一些简单的 C/Assembler 代码,它正在执行这个 InterlockedCompareExchange 魔术。如果使用相同的汇编语法,这应该可以跨 Intel i386 或 amd64 平台移植。
    • 在这种情况下:google.com/search?q=rwlock+interlockedcompareexchange -- 另请注意,InterlockedCompareExchange() 的 x86 指令是“lock cmpxchg”。
    • @Lothar - 如果你想要适当的阻塞,你不能完全避免系统调用 - 即,当一个线程无法获取锁时,它应该进入睡眠状态。系统调用只发生在有争议的情况下——如果你从不想要一个系统调用,唯一的选择就是自旋循环,差不多。我在下面添加了一个答案,描述了您将如何推出自己的产品。
    【解决方案2】:

    您当然可以使用与 slim rwlock 相同的想法来创建自己的想法(至少我想象他们会这样做,因为这相当简单)。我在this other question 中详细概述了该方法。

    对于您的情况,您几乎可以忽略“公平”方面,但实现基本相同。特别是,如果你愿意让无限的读者流阻塞写者,那么当锁中已经有读者时,你总是让读者进来(即状态(2)和(3)或多或少地一起崩溃)。

    在您的情况下,对于跨平台角度,您需要使用 either windows 事件或 pthread condvars 来实现阻塞 - 但在任何一种情况下,细节都是相似的。或者,如果你真的想完全避免阻塞,你唯一的选择就是旋转(最好使用pause 指令对 CPU 更好),这可以通过移除整个回退到阻塞代码使事情变得更容易。

    一个好的实现可能是几百个 LOC。我写了一个(封闭的源代码,我不能分享它),它的性能非常好(实际上比纤细的锁要好)。

    【讨论】:

      猜你喜欢
      • 2018-04-17
      • 2016-03-28
      • 1970-01-01
      • 2017-06-10
      • 2018-03-17
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      相关资源
      最近更新 更多