簡體   English   中英

SRW Lock 可以用作二進制信號量嗎?

[英]Can SRW Lock be used as a binary semaphore?

Slim Reader/Writer (SRW) Locks是 Windows 中的同步原語,從 Windows Vista 開始可用。

名稱和接口表明它應該用作非定時共享非遞歸互斥鎖。 但是,通常也將其用作非共享互斥體,以避免CRTICAL_SECTION開銷(僅使用獨占 API)。

我注意到它也可以用作二進制信號量。 This can come handy, as other semaphores available in Windows APIs - Event object and Semaphore object - are always a kernel call, so it is probably the only lightweight semaphore readily available from Windows API (and C++ has semaphores starting C++20, and 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 Chen 是對的。 應用程序驗證程序報告相關代碼的錯誤:

有問題的代碼會產生此錯誤:

=======================================
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.

=======================================

截至目前,該文檔還明確禁止在不同的線程中發布,請參閱ReleaseSRWLockExclusiveReleaseSRWLockShared

SRW 鎖必須由獲得它的同一線程釋放。 您可以使用 Application Verifier 來幫助驗證您的程序是否正確使用 SRW 鎖(從 Basic 組啟用 Locks checker)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM