2009-10-06 77 views
1

我們正在嘗試構建一個類,該類提供MFC CRecordset(或者確實是CODBCRecordset類)的線程安全性。對於像打開和移動記錄集這樣的各種功能(我們將這些調用與關鍵部分一起),實際上一切看起來都很順利,但是,仍然存在一個問題,這個問題似乎在實踐中引入了死鎖。構造一個C++對象(MFC CRecordset)線程安全

的問題似乎在於我們的構造,就像這樣:

CThreadSafeRecordset::CThreadSafeRecordset(void) : CODBCRecordset(g_db) 
{ // <-- Deadlock! 
} 

另一個線程可能是具有在CThreadSafeRecordset ::關閉(),儘管我們守着封閉關閉通話結束了,但沒有按因爲構造函數不知道線程,所以它並不重要。我假設原來的CRecordset類是罪魁禍首,在施工時做壞事。我已經尋找編程技術來解決這個問題,但我不確定什麼是最好的解決方案?由於我們沒有代碼,並且無法控制構造函數中的其他代碼,所以我們無法在關鍵部分中包含任何特殊的東西......?

更新:感謝您的輸入;我已經標記了我最終以什麼作爲我的問題的答案。結合返回shared_ptr作爲返回的實例,以便更新現有線程未知代碼。

回答

2

您可以使CThreadSafeRecordset構造函數爲private,然後提供一個公共工廠方法,該方法參與您的鎖定並返回一個實例。

1

如果沒有辦法讓CODBCRecordset將其線程不安全的操作從構造函數中移出(默認構造函數後接Initialize()調用,比如說),那麼您始終可以使用組合而不是繼承。讓CThreadSafeRecordset成爲CODBCRecordset的一個包裝,而不是它的一個子類。這樣,只要你喜歡,你可以明確地構建你的記錄集,並且可以用適當的任何嚴謹來捍衛它。

當然,缺點是你必須每包含你想公開的方法,甚至那些與你的線程保證無關的方法。 Cpp文件中的一個C宏(這樣它不能逃脫並折磨你的客戶)可能會有所幫助。