2015-12-10 94 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