我完全被windows SRW实现的质量所折服。它比临界区更快,而且只有几个字节的内存开销。
不幸的是,它只有Windows Vista/Windows 7。
由于这是一个纯用户领域的实现,有人知道它是否有跨平台的实现吗?有没有人对这些解决方案进行了逆向工程?
还有,我不想添加像boost这样的东西,只是为了引入一个低于100LOC的解决方案。
发布于 2009-12-08 16:27:08
如果你想要符合某种标准的“便携”的东西...如果你使用的是POSIX线程,有pthread_rwlock_init()
和friends。当然,这些通常不是用在Windows上,而是用在Unix类型的OSes上。
但是,如果您的意思是“可移植到Windows的多个版本...”在实现读写锁的ntdll
中有一些未记录的调用。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
GetProcAddress()
这些内容。
至于引用的结构...以下是葡萄酒的宣言:
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实现,并根据其他操作自己实现它……比方说InterlockedCompareExchange()
,或者更高级别的原语,比如信号量和事件。
发布于 2016-10-14 01:46:08
当然,您也可以使用与slim rwlock相同的想法来创建自己的应用程序(至少我认为他们是这样做的,因为这是相当简单的)。我在this other question中详细介绍了这种方法。
对于您的情况,您可以忽略“公平”方面,但实现本质上是相同的。特别是,如果您愿意让不确定的读取器流阻止写入器,则总是在锁中已经有读取器时让读取器进入(即,状态(2)和(3)或多或少一起折叠)。
在您的情况下,对于跨平台角度,您将需要使用windows事件或pthread condvars实现阻塞-但在这两种情况下,细节都是相似的。或者,如果您真的想要完全避免阻塞,那么您唯一的选择就是旋转(理想情况下,使用pause
指令对CPU更好),这使得事情变得更加容易,因为它消除了阻塞代码的整个回退机制。
一个好的实现可能是几百个LOC。我写了一个(关闭源码,我不能分享它),它的性能非常好(事实上,比slim lock更好)。
https://stackoverflow.com/questions/1865412
复制相似问题