首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SRW锁可以用作二进制信号量吗?

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

Stack Overflow用户
提问于 2020-06-27 19:37:46
回答 1查看 298关注 0票数 0

Slim阅读器/作家(SRW)锁是Windows中的同步原语,可从Windows开始使用。

名称和接口建议将其用作非时间共享、非递归互斥。但是,为了避免CRTICAL_SECTION开销(只使用独占的API),通常也使用它作为非共享互斥。

我注意到它也作为二进制信号量工作。这会派上用场,因为Windows中可用的其他信号量--事件对象和信号量对象--总是一个内核调用,因此它可能是Windows中唯一一个随时可用的轻量级信号量( C++具有启动C++20的信号量,boost线程也不提供信号量)。

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

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

我期待的答案是:

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

例子-这不会挂起

代码语言:javascript
复制
#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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-28 04:49:31

@雷蒙德·陈是对的。应用程序验证程序报告有关代码的错误:

所述代码产生此错误:

代码语言:javascript
复制
=======================================
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来帮助验证您的程序是否正确地使用SRW锁(从基本组启用锁定检查器)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62614716

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档