2010-12-06 128 views
3

我們是MFC中的一對新手,我們正在構建一個多線程應用程序。我們遇到URL中的文章,警告我們不要使用CCriticalSection,因爲它的實現被破壞了。我們很想知道是否有人有使用CCriticalSection的經驗,並且您遇到任何問題或錯誤?如果我們使用VC++ 2008來構建我們的應用程序,是否可以使用CCriticalSection和生產?是Ccriticalsection可用於生產?

http://www.flounder.com/avoid_mfc_syncrhonization.htm

THX

回答

11

我認爲這篇文章是基於對CSingleLock的基本誤解以及如何使用它。

您無法多次鎖定相同的CSingleLock,但您不應該這樣做。正如其名稱所示,CSingleLock用於鎖定某件事。

每個CSingleLock只管理其他對象上的一個鎖(例如,在構建過程中傳遞它的CCriticalSection),目的是在CSingleLock超出範圍時自動釋放該鎖。

如果要多次鎖定底層對象,則可以使用多個CSingleLock;你不會使用單個CSingleLock並嘗試多次鎖定它。

錯誤(他的例子):

CCriticalSection crit; 
CSingleLock lock(&crit); 
lock.Lock(); 
lock.Lock(); 
lock.Unlock(); 
lock.Unlock(); 

右:

CCriticalSection crit; 
CSingleLock lock1(&crit); 
CSingleLock lock2(&crit); 
lock1.Lock(); 
lock2.Lock(); 
lock2.Unlock(); 
lock1.Unlock(); 

更妙的(所以你得到RAII):

CCriticalSection crit; 
// Scope the objects 
{ 
    CSingleLock lock1(&crit, TRUE); // TRUE means it (tries to) locks immediately. 
    // Do stuff which needs the lock (if IsLocked returns success) 
    CSingleLock lock2(&crit, TRUE); 
    // Do stuff which needs the lock (if IsLocked returns success) 
} 
// crit is unlocked now. 

(當然,你決不會有意像這樣在一個塊中的同一底層關鍵部分獲得兩個鎖。通常只會發生在調用的結果中這些函數在已經擁有自己的鎖的其他東西內部獲取鎖的函數)。

(此外,您應該檢查CSingleLock.IsLocked以查看鎖是否成功。爲了簡潔起見,我已經將這些支票離開了,因爲它們被排除在原始示例之外。)

如果CCriticalSection本身遭受同樣的問題,那肯定是一個問題,但他沒有提供證據表明我可以看到。 (也許我錯過了一些東西,在我的MFC安裝中找不到CCriticalSection的源代碼來驗證這種方式)

+0

他對鎖應該做什麼的理解似乎基於comp-sci背景或基於他的論點的語氣來實現來自其他平臺和/或實現的類似命名的鎖。 – Arafangion 2010-12-06 12:24:49

0

那篇文章認爲,使用這些原語的簡單情況都很好,但執行起來違反了應該預計它們的語義。

基本上,它表明如果你使用它作爲一個非遞歸鎖,你要注意永遠保證鎖是有效的(即不被放棄),那麼你應該沒問題。

然而,文章的抱怨說,限制是不可原諒的。