关键部分总是更快吗?

人气:1,032 发布:2022-09-11 标签: winapi synchronization c++ critical-section

问题描述

我在调试一个多线程应用,发现CRITICAL_SECTION的内部结构.我发现 CRITICAL_SECTION 的数据成员 LockSemaphore 很有趣.

I was debugging a multi-threaded application and found the internal structure of CRITICAL_SECTION. I found data member LockSemaphore of CRITICAL_SECTION an interesting one.

看起来 LockSemaphore 是一个自动重置事件(不是顾名思义的信号量),当线程第一次等待 Critcal Section 被其他线程锁定.

It looks like LockSemaphore is an auto-reset event (not a semaphore as the name suggests) and operating system creates this event silently when first time a thread waits on Critcal Section which is locked by some other thread.

现在,我想知道关键部分总是更快吗?Event 是一个内核对象,每个关键部分对象都与事件对象相关联,那么与其他内核对象(如 Mutex)相比,Critical Section 如何更快?此外,内部事件对象实际上如何影响关键部分的性能?

Now, I am wondering is Critical Section always faster? Event is a kernel object and each Critical section object is associated with event object then how Critical Section can be faster compared to other kernel objects like Mutex? Also, how does internal event object actually affects the performance of Critical section ?

这是CRITICAL_SECTION的结构:

struct RTL_CRITICAL_SECTION
{
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread;
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;
};

推荐答案

当他们说临界区快"时,他们的意思是如果它还没有被另一个线程锁定,那么获取一个临界区很便宜".

When they say that a critical section is "fast", they mean "it's cheap to acquire one when it isn't already locked by another thread".

[请注意,如果它 已经被另一个线程锁定,那么它的速度有多快并不重要.]

[Note that if it is already locked by another thread, then it doesn't matter nearly so much how fast it is.]

之所以这么快,是因为在进入内核之前,它在其中一个 LONG 字段(可能在 >LockCount 字段),如果成功则认为已获得锁而没有进入内核.

The reason why it's fast is because, before going into the kernel, it uses the equivalent of InterlockedIncrement on one of those LONG field (perhaps on the the LockCount field) and if it succeeds then it considers the lock aquired without having gone into the kernel.

InterlockedIncrement API 我认为是在用户模式下作为LOCK INC"操作码实现的......换句话说,您可以在完全不执行任何环转换到内核的情况下获得一个无争议的关键部分.

The InterlockedIncrement API is I think implemented in user mode as a "LOCK INC" opcode ... in other words you can acquire an uncontested critical section without doing any ring transition into the kernel at all.

624