TryEnterCriticalSection的用例是什么?

时间:2019-07-18 11:30:12

标签: winapi critical-section

自1990年代以来,我一直在使用Windows CRITICAL_SECTION,并且自TryEnterCriticalSection函数问世以来,我就一直知道它。我知道这应该可以帮助我避免上下文切换以及所有其他情况。

但是我突然发现我从未使用过它。不止一次。  我也从未觉得我需要使用它。实际上,我想不出我会的情况。

通常,当我需要获得某件商品的排他锁时,我需要该锁,现在我需要它。我不能推迟到以后。我当然不能只说:“哦,我毕竟不会更新这些数据”。所以我需要EnterCriticalSection,而不是TryEnterCriticalSection

那么TryEnterCriticalSection的用例到底是什么?

我已经对此进行了Google搜索。我已经找到了许多关于 如何 的使用方法的简短描述,但几乎没有 为什么 的真实示例。 。我确实找到了这个示例from Intel,但坦率地说并没有太大帮助:

CRITICAL_SECTION cs;

    void threadfoo()
    {
        while(TryEnterCriticalSection(&cs) == FALSE)
        {
             // some useful work
        }

        // Critical Section of Code

        LeaveCriticalSection (&cs);
    }

    // other work
}

在等待锁的情况下可以执行“一些有用的工作”的情形到底是什么?我很想避免线程争用,但是在我的代码中,当我需要关键部分时,我已经被迫做所有这些“有用的工作”,以便获得要共享的更新值数据(首先需要关键部分)。

有人有真实的例子吗?

3 个答案:

答案 0 :(得分:2)

例如,您可能有多个线程,每个线程都产生大量消息(某种事件),所有消息都需要进入共享队列。

由于共享队列上的锁将经常发生争用,因此每个线程都可以有一个本地队列,然后,只要对当前线程的TryEnterCriticalSection调用成功,它将复制它在本地的所有内容排队进入共享的队列,然后再次释放CS。

答案 1 :(得分:1)

在C ++ 11中,std::lock采用了避免死锁算法。

在C ++ 17中,这已详细阐述为std::scoped_lock类。

此算法尝试以一种顺序锁定互斥锁,然后以另一种顺序锁定互斥锁,直到成功为止。需要try_lock才能实现此方法。

在C ++中拥有try_lock方法称为Lockable命名需求,而只有lockunlock的互斥锁是BasicLockable

因此,如果您在CTRITICAL_SECTION上构建C ++互斥锁,并且想要实现Lockable,或者想要直接在CRITICAL_SECTION上实现锁避免,则需要TryEnterCriticalSection


此外,您可以在TryEnterCriticalSection上实现定时互斥。您可以对TryEnterCriticalSection进行几次迭代,然后以增加的延迟时间来调用Sleep,直到TryEnterCriticalSection成功或截止日期到期为止。不过,这不是一个好主意。基于用户空间WIndows同步对象的实时定时互斥锁是在SleepConditionVariableSRWSleepConditionVariableCSWaitOnAddress上实现的。

答案 2 :(得分:0)

因为Windows CS是递归的,TryEnterCriticalSection允许线程检查它是否已经拥有CS而没有停滞的风险。

另一种情况是,如果您有一个线程偶尔需要执行一些锁定的工作,但通常还要执行其他操作,则可以使用TryEnterCriticalSection并仅在实际获得锁定的情况下才执行锁定的工作。