2015-12-10 62 views
4

在TCriticalSection上调用TryEnter方法时,结果始终为真。当然,如果它能够获得锁定,这应该只会恢复真实?TCriticalSection TryEnter方法总是返回True

var 
    MyCritSect: TCriticalSection; 

begin 
    MyCritSect := TCriticalSection.Create; 
    try 
    // MyCritSect.Enter; 
    Writeln(BoolToStr(MyCritSect.TryEnter, True)); // This should return True 
    Writeln(BoolToStr(MyCritSect.TryEnter, True)); // This should return False? 
    Readln; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 

即使你取消注释MyCritSect.Enter;线仍然为两个呼叫TryEnter返回True。

我使用德尔福XE和Windows 10

回答

4

关键部分是re-entrant locks。从documentation

当一个线程拥有一个关键部分,它可以对EnterCriticalSection的或TryEnterCriticalSection额外通话无阻塞执行。这可以防止线程在等待它已经拥有的关键部分时发生死锁。

如果从不同的线程创建并调用TryEnter将失败,并且第一个线程已经拥有该锁。

+0

谢谢大卫,我认为TSpinLock可能更适合我的需求。 –

+1

因为我们不知道动机,所以我无法就这种情况提供任何意见。旋转锁确实会烧毁CPU,所以它们只能用于小区域的低争用。 –

+0

@DonovanBoddy如果你试图在同一个线程上做一个自旋锁,那么你会遇到麻烦,因为它会挂起或者像临界区一样依赖于实现。 – Graymatter