SRW 锁可以用作二进制信号量吗?



Slim Reader/Writer (SRW( Locks 是 Windows 中的同步原语,可从 Windows Vista 开始使用。

名称和接口建议将其用作非定时共享非递归互斥锁。但是,通常也可以将其用作非共享互斥锁,以避免CRTICAL_SECTION开销(仅使用独占 API(。

我注意到它也可以用作二进制信号量。这可以派上用场,因为Windows API中可用的其他信号量 - 事件对象和信号量对象 - 始终是内核调用,因此它可能是Windows API中唯一可用的轻量级信号量(并且C++具有从C++20开始的信号量,并且boost线程也不提供信号量(。

但这可靠吗?具体来说,我没有在文档中找到可以这样使用的明确信息。

但是,我没有找到任何禁止这种用法的东西。文件似乎不确定。

我期待的答案:

  • 也许有人可以指出我允许或禁止使用信号量的文档措辞
  • 也许这种用法有一些实践经验
  • 也许直接参与 SRW 锁实现的人可以澄清(我认为有一些机会(

示例 - 这不会挂起

#include <Windows.h>
#include <atomic>

SRWLOCK lock = SRWLOCK_INIT;
std::atomic<bool> can_release{ false };
DWORD CALLBACK Thread1(LPVOID)
{
for (int i = 0; i < 3; i++)
{
while (!can_release)
{
// spin
}
can_release = false;
::ReleaseSRWLockExclusive(&lock);
}
return 0;
}

DWORD CALLBACK Thread2(LPVOID)
{
for (int i = 0; i < 3; i++)
{
can_release = true;
::AcquireSRWLockExclusive(&lock);
}
return 0;
}
int main() {
::AcquireSRWLockExclusive(&lock);
HANDLE h1 = ::CreateThread(nullptr, 0, Thread1, nullptr, 0, nullptr);
HANDLE h2 = ::CreateThread(nullptr, 0, Thread2, nullptr, 0, nullptr);
::WaitForSingleObject(h1, INFINITE);
::WaitForSingleObject(h2, INFINITE);
::CloseHandle(h1);
::CloseHandle(h2);

return 0;
}

@Raymond陈是对的。应用程序验证程序报告相关代码的错误:

有问题的代码会产生此错误:

=======================================
VERIFIER STOP 0000000000000255: pid 0x1A44: The SRW lock being released was not acquired by this thread. 
00007FF73979C170 : SRW Lock
00000000000025CC : Current ThreadId.
00000000000043F4 : ThreadId of the thread that acquired the SRW lock.
000001C1BEA8BF40 : Address of the acquire stack trace. Use dps <address> to see where the SRW lock was acquired.

=======================================
This verifier stop is continuable.
After debugging it use `go' to continue.
=======================================

=======================================
VERIFIER STOP 0000000000000253: pid 0x1A44: The SRW lock is being acquired recursively by the same thread. 
00007FF73979C170 : SRW Lock
000001C1BEA8BF40 : Address of the first acquire stack trace. Use dps <address> to see where the SRW lock was acquired.
0000000000000000 : Not used
0000000000000000 : Not used

=======================================
This verifier stop is continuable.
After debugging it use `go' to continue.
=======================================

截至目前,文档还明确禁止在不同的线程中发布,请参阅 ReleaseSRWLockExclusive, ReleaseSRWLockShared:

SRW 锁必须由获取它的同一线程释放。可以使用应用程序验证程序来帮助验证程序是否正确使用 SRW 锁(从"基本"组启用"锁检查器"(。

最新更新