Slim Reader/Writer (SRW) Locksは Windows の同期プリミティブであり、Windows Vista 以降で使用できます。
名前とインターフェイスは、時間制限のない共有非再帰ミューテックスとして使用する必要があることを示唆しています。CRTICAL_SECTION
ただし、 (排他的 API のみを使用して) オーバーヘッドを回避するために、非共有ミューテックスとしても使用するのが一般的です。
バイナリセマフォとしても機能することに気付きました。Windows API で使用可能な他のセマフォ (イベント オブジェクトとセマフォ オブジェクト) は常にカーネル呼び出しであるため、これは便利です。おそらく Windows API からすぐに使用できる唯一の軽量セマフォです (C++ には C++20 から始まるセマフォがあり、ブースト スレッドもセマフォを提供しません)。
しかし、これは信頼できますか?具体的には、この方法で使用できるという明示的な情報がドキュメントに見つかりませんでした。
しかし、この使用法を禁止するものは見つかりませんでした。ドキュメントは不確かなようです。
私が答えとして期待していること:
- セマフォの使用を許可または禁止する文書の文言を教えてくれる人がいるかもしれません
- たぶん、そのような使用法にはいくつかの実践的な経験があります
- おそらく、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;
}