c++ - ADODB 记录集中的访问冲突关闭
问题描述
仍在试图弄清楚 ADODB 的连接发生了什么以及为什么会发生某种崩溃。
问题是我们的代码中存在内存泄漏:
void getDetailConfig()
{
m_displayConf = new TestDetailDisplayCfg();
}
这个函数经常被调用,所以基本的内存泄漏。用唯一的指针修复它
void getDetailConfig()
{
m_displayConf = std::make_unique<TestDetailDisplayCfg>();
}
是的,但是现在 ADODB 的 Recordset15::Close 内部开始发生访问冲突。
inline HRESULT Recordset15::Close ( ) {
HRESULT _hr = raw_Close();
if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
return _hr;
}
LaneControl.exe 中 0x679E653F (msado15.dll) 处的未处理异常:0xC000041D:用户回调期间遇到未处理异常。
所以以正确的方式调用所有析构函数会导致一个新问题,记录集在某处打开和关闭。
调试后发现 getDetailConfig 是从两个不同的线程调用的。
线程1
void updateIconStatus()
{
getDetailConfig();
}
线程 ID 5bA8
线程2
void CVTSDetailDisplay::setCurrentTestIconStatus(int status)
{
m_CurrentDialog->getDetailConfig();
}
线程 ID 6A4C
因此,这两个线程调用 getDetailConfig ,其中记录集已关闭,该记录集在另一个线程上打开,COM 对象已释放,等等。
这是您无法在另一个线程上关闭 ADO 记录集的问题吗?它更像是一种竞争条件吗?在 ADODB 级别这里出了什么问题?
解决方案
我认为这是一个竞争条件。
如果getDetailConfig()
之前已经调用了该函数,然后两个线程都调用了getDetailConfig()
,这可能导致两个线程同时调用(之前存在的对象的)析构函数(std::unique_ptr
本质上不是线程安全的 AFAIK)。
然后,您需要确保交换指针的关键部分,例如添加std::mutex m_mutex;
为类的成员(理想情况下添加到成员列表中的第一位,因此它比m_displayConf
成员保持有效的时间更长),然后添加
void getDetailConfig()
{
std::unique_lock<std::mutex> lock(m_mutex);
m_displayConf = std::make_unique<TestDetailDisplayCfg>();
}
确保线程之间的交换被锁定。
推荐阅读
- google-bigquery - Googe Big-Query - 无法合并 3 个表 - 出现错误“无法运行查询”
- reactjs - 在 React 中的组件之前拉起 props
- php - WordPress 循环,第一行 3 列,其余 4 列
- python - 使用 msvcrt.getwch() 时,Tkinter config() 不会更新 while 循环中的标签
- visual-studio - 有没有办法避免在我们关闭另一个文件时自动聚焦在打开的文件上的工作区?-- VisualStudio 代码 v1.46.0
- javascript - 如果我检测到窗口模糊并暂停视频,VIMEO 嵌入播放器的行为会很奇怪
- erlang - Erlang消息发送和接收与多个进程
- hadoop - Flume Twitter 流问题
- javascript - 几秒钟后隐藏项目
- javascript - Jest 测试中非默认类导出的模拟方法