构造一个C++对象(MFC CRecordset)线程安全

问题描述:

我们正在尝试构建一个类,该类提供MFC CRecordset(或者确实是CODBCRecordset类)的线程安全性。对于像打开和移动记录集这样的各种功能(我们将这些调用与关键部分一起),实际上一切看起来都很顺利,但是,仍然存在一个问题,这个问题似乎在实践中引入了死锁。构造一个C++对象(MFC CRecordset)线程安全

的问题似乎在于我们的构造,就像这样:

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

另一个线程可能是具有在CThreadSafeRecordset ::关闭(),尽管我们守着封闭关闭通话结束了,但没有按因为构造函数不知道线程,所以它并不重要。我假设原来的CRecordset类是罪魁祸首,在施工时做坏事。我已经寻找编程技术来解决这个问题,但我不确定什么是最好的解决方案?由于我们没有代码,并且无法控制构造函数中的其他代码,所以我们无法在关键部分中包含任何特殊的东西......?

更新:感谢您的输入;我已经标记了我最终以什么作为我的问题的答案。结合返回shared_ptr作为返回的实例,以便更新现有线程未知代码。

您可以使CThreadSafeRecordset构造函数为private,然后提供一个公共工厂方法,该方法参与您的锁定并返回一个实例。

如果没有办法让CODBCRecordset将其线程不安全的操作从构造函数中移出(默认构造函数后接Initialize()调用,比如说),那么您始终可以使用组合而不是继承。让CThreadSafeRecordset成为CODBCRecordset的一个包装,而不是它的一个子类。这样,只要你喜欢,你可以明确地构建你的记录集,并且可以用适当的任何严谨来捍卫它。

当然,缺点是你必须每包含你想公开的方法,甚至那些与你的线程保证无关的方法。 Cpp文件中的一个C宏(这样它不能逃脱并折磨你的客户)可能会有所帮助。