所以这是我的问题。我有一个在VM上运行的Linux程序,它通过dlopen使用OpenCL来执行一些命令。在程序执行的大约一半时,它将会休眠,并且在恢复时不能对GPU上的任何状态做出任何假设(事实上,驱动程序可能已经重新加载,而物理GPU可能已经改变)。在休眠之前调用dlclose并且这会卸载OpenCL内存区域(这是一件好事),但是OpenCL使用的库(在这种情况下是cuda和nvidia库)不会被卸载。因此,当程序恢复并试图再次重新使用一切时,事情就会失败。
所以我正在寻找的是一种有效取消链接/卸载OpenCL正在使用的共享库的方法,以便它可以正确地“重启”自身。作为一个注释,只要需要,过程本身可以在此过渡期间暂停(停止),但可能不会被杀死。
另外,假设我正在使用root访问权限,并且对我可以修改/触摸的文件有或多或少的限制。
答案 0 :(得分:0)
如果他们没有卸载,这可能是因为某些东西保留了对它们的引用,或者它们设置了nodelete
标志,或者因为dlclose
的实现不支持卸载他们出于其他原因。请注意,dlclose
无需卸载任何内容:
应用程序编写者可以使用dlclose()在进程的一部分上创建一个intent语句,但是这个语句不会对实现产生任何要求。当符号表句柄关闭时,实现可以卸载在打开符号表句柄时由dlopen()加载的可执行目标文件以及在使用由句柄标识的符号表句柄时由dlsym()加载的可执行目标文件。 / p>
来源:http://pubs.opengroup.org/onlinepubs/9699919799/functions/dlclose.html
您遇到的问题是为什么在用户空间进程中加载图形驱动程序是一个完全糟糕的想法的一个症状,但解决这个问题既是技术上的挑战也是政治挑战(很多人都是反对修复它。)
唯一的短期实际解决方案可能是将使用这些库的代码分解为一个单独的进程,您可以杀死并重新启动,并通过某种IPC机制与之交谈,或者只是将整个程序序列化为其状态并在简历上重新执行。
答案 1 :(得分:0)
对于一个不太短期的实际解决方案,您可能会尝试在加载的库上强制重新初始化序列,和/或强制卸载。
libdl只是一个普通的库,您可以复制,修改和链接而不是使用系统库。一种选择是禁用RTLD_NODELETE
处理。另一个是为给定的库运行DT_FINI
/ DT_INIT
序列。
dl_iterate_phdr
,如果可用,可以用来做同样的事情,而无需修改libdl。
在libdl中浏览和/或使用LD_DEBUG
(如果支持)可能会解释为什么它首先没有被卸载。