自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
}
在等待锁的情况下可以执行“一些有用的工作”的情形到底是什么?我很想避免线程争用,但是在我的代码中,当我需要关键部分时,我已经被迫做所有这些“有用的工作”,以便获得要共享的更新值数据(首先需要关键部分)。
有人有真实的例子吗?
答案 0 :(得分:2)
例如,您可能有多个线程,每个线程都产生大量消息(某种事件),所有消息都需要进入共享队列。
由于共享队列上的锁将经常发生争用,因此每个线程都可以有一个本地队列,然后,只要对当前线程的TryEnterCriticalSection
调用成功,它将复制它在本地的所有内容排队进入共享的队列,然后再次释放CS。
答案 1 :(得分:1)
在C ++ 11中,std::lock
采用了避免死锁算法。
在C ++ 17中,这已详细阐述为std::scoped_lock
类。
此算法尝试以一种顺序锁定互斥锁,然后以另一种顺序锁定互斥锁,直到成功为止。需要try_lock
才能实现此方法。
在C ++中拥有try_lock
方法称为Lockable
命名需求,而只有lock
和unlock
的互斥锁是BasicLockable
。
因此,如果您在CTRITICAL_SECTION
上构建C ++互斥锁,并且想要实现Lockable
,或者想要直接在CRITICAL_SECTION
上实现锁避免,则需要TryEnterCriticalSection
此外,您可以在TryEnterCriticalSection
上实现定时互斥。您可以对TryEnterCriticalSection
进行几次迭代,然后以增加的延迟时间来调用Sleep
,直到TryEnterCriticalSection
成功或截止日期到期为止。不过,这不是一个好主意。基于用户空间WIndows同步对象的实时定时互斥锁是在SleepConditionVariableSRW
,SleepConditionVariableCS
或WaitOnAddress
上实现的。
答案 2 :(得分:0)
因为Windows CS是递归的,TryEnterCriticalSection允许线程检查它是否已经拥有CS而没有停滞的风险。
另一种情况是,如果您有一个线程偶尔需要执行一些锁定的工作,但通常还要执行其他操作,则可以使用TryEnterCriticalSection并仅在实际获得锁定的情况下才执行锁定的工作。