OpenCL - c++包装器-动态库中的上下文取消初始化导致访问冲突
OpenCL - C++ wrapper - Context deinitialization in dynamic library leads to access violation
我想构建一个库(windows系统上的共享库),它提供了一些默认配置(上下文,命令队列,…)。问题是,当应用程序试图退出时,会出现访问冲突。我的第一个猜测是,这可能是我的包装器实现的问题,但后来我建立了一个测试用例,使用官方的c++包装器(cl.hpp
)。
boost::optional<cl::Context> cpuContext;
void cpu() {
cpuContext = cl::Context(CL_DEVICE_TYPE_CPU);
}
应用端
int main(int argc, char** argv) {
cpu();
}
非常简单的东西…
有趣的是,这种情况只发生在英特尔运行时(不能测试英特尔gpu),而不是Nvidia提供的运行时。如果在应用程序端声明了cpuContext
变量,也不会发生这种情况。
我的问题是:
这是英特尔运行时的一个bug,还是我错过了一些东西,遇到了未定义的行为?
如果尝试从DllMain释放OpenCL对象,可能会出现一个非常微妙的问题。它可以显示您所看到的行为,但可能有些不可预测或断断续续。首先,简单介绍一下背景:
当你加载OpenCL.dll时,在大多数平台上,你正在加载一个标准化的可安装客户端驱动程序(ICD),它是你的代码和系统上可能存在的各种实现之间的一个垫片。你可以在这里读到更多。ICD是一个DLL,它使用Windows LoadLibrary调用来加载由OpenCL供应商(Intel, AMD等)提供的DLL。
使用LoadLibrary不会更新Windows DLL依赖跟踪结构。因此,当进程关闭时,无法知道这些dll被卸载的顺序。在这种情况下,当调用全局OpenCL上下文对象的析构函数时,供应商提供的OpenCL dll可能已经被卸载了。这有可能导致访问冲突。你可以在这里读到更多。
考虑到所有这些,我将避免设计需要在全局对象析构函数或DllMain中调用OpenCL函数的DLL。
相关文章:
- 挂起和取消挂起一个文件DLL
- #为""定义宏;静态";针对不同的上下文
- 与互斥锁相比,旋转锁可以保证上下文切换
- 如何取消对nullptr的屏蔽,返回正确的对象
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- C++取消引用指针.为什么会发生变化
- 为什么我不能使用 EGL 创建无头 OpenGl 上下文?
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 取消引用运算符不能重载
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 如何在Qt中取消捕获字符串
- 为什么在逗号分隔符上下文中将预增量的结果强制转换为void
- 错误"Could not find Boost"(缺少:上下文标头)
- 使用 mod_gsoap 部署服务时,如何在 Gsoap 中更改 soap 上下文的模式?
- 如何使用 TStyleManager::UnRegisterStyle() 取消注册样式
- GLEW/GLUT:调用init并创建一个窗口后,取消初始化并重新初始化?
- C++ 关于指针取消引用的技术问题
- OpenCL - c++包装器-动态库中的上下文取消初始化导致访问冲突
- Qt翻译:在ts文件中,对于“确定”、“保存”、“取消”等标准按钮,我应该使用什么上下文