c++ - 从静态变量的析构函数调用 Windows 7 上的 std::conditional_variable notify() 问题
问题描述
当从静态变量的析构函数调用 Windows 7 时,std::conditional_variable notify()
我遇到了问题。notify_all()
对象看起来像这样(逻辑被简化):
class SomeObject
{
public:
~SomeObject()
{
StopThreadAndWait();
}
void StopThreadAndWait()
{
/* some logic */
m_stop = true;
m_procesTasks.notify_one(); // <- the problem is here
if (m_thread.joinable())
m_thread.join();
}
private:
...
bool m_stop;
std::mutex m_workQueueSync;
std::thread m_thread;
std::condition_variable m_procesTasks;
};
SomeObject -- 是一个静态变量。
当我们打电话时~SomeObject()
-m_thread
已经停止了。但在 Windows 7 上,我们遇到了麻烦。
在调用堆栈的顶部:(这是应用程序的唯一线程)
ntdll.dll!ZwReleaseKeyedEvent()
ntdll.dll!RtlpWakeConditionVariable()
ntdll.dll!RtlWakeConditionVariable()
MSVCP140D.dll!__crtWakeAllConditionVariable(_RTL_CONDITION_VARIABLE * pCond)
MSVCP140D.dll!Concurrency::details::stl_condition_variable_win7::notify_one()
....
ntdll.dll!RtlExitUserProcess()
...
我知道,静态对象的析构函数中的同步 - 不好的做法(它是遗留代码)有很多方法可以修复它。
但是,这似乎是在 Win 7 的 140 运行时中实现 STL 的错误(在 Win 10 上一切正常)。如果是的话,我在互联网上找不到任何关于它的信息
更新:
在另一个项目中遇到了这个问题,所以对于任何可能遇到这个问题的人:
问题:
似乎在 Win7 上执行条件变量时出现了一些问题(由于Concurrency::details::stl_condition_variable_win7::notify_one()
)
出现,当有一个条件变量时,我想等待该变量的线程由于某种原因而终止(在我的情况下 - 由于进程关闭)
在这种情况下std::conditional_variable::notify()
会导致挂起。
可能的解决方案
最好的解决方案 - 只是为了修复架构,因为静态对象中的线程 - 不是最好的方法。
另一种选择 - 使用 boost 而不是 STL
解决方案
我遇到了同样的问题,只在 windows 7 上。相同的代码在 Windows 10 上运行。当我们到达 notify_all(我的案例)或 notify_one(此处)时,似乎 STL condition_variable 的基础架构已经以某种方式被拆除。
在我的情况下,有 8 个线程在等待,但是当程序挂起时它们都死了,所以 notify_all 完成了它的工作,但从未返回。在我的调用堆栈中有一个包含 win7 的函数名称,因此很可能在 win7 和 win 10 中运行不同的代码:
ntdll.dll!ZwReleaseKeyedEvent() Unknown
ntdll.dll!string "Enabling heap debug options\n"() Unknown
msvcp140d.dll!__crtWakeAllConditionVariable(_RTL_CONDITION_VARIABLE * pCond) Line 450 C++
msvcp140d.dll!Concurrency::details::stl_condition_variable_win7::notify_all() Line 188 C++
msvcp140d.dll!do_signal(_Cnd_internal_imp_t * cond, int all) Line 80 C++
msvcp140d.dll!_Cnd_broadcast(_Cnd_internal_imp_t * cond) Line 101 C++
cvie64.dll!std::condition_variable::notify_all() Line 596 C++
cvie64.dll!ctpl::thread_pool::interrupt(bool kill) Line 166 C++
推荐阅读
- python - PI π Calculation loading system
- r - 当数据不适合 R 中的内存时的选项
- html - 在不知道图像方向的情况下,将图像以较小的一侧适合容器
- node.js - 猫鼬分页不会显示页数
- oracle - 如何在oracle中获得相同日期的数字之间的差异?
- c++ - Rcpp:我无法将参数传递给 C++ 函数
- python - python pandas“无法设置列不匹配的行”错误
- android - PWA 在后台播放媒体
- python - AWS XRay: Unable to write to /tmp/.aws-xray/initialized. Failed to signal SDK initialization
- javascript - 使用 $resource 工厂无法发布纯文本数据