所以我正在研究共享库,我读到在进程终止时执行隐式 dlclose()
。我想知道谁负责这个电话。例如,如果我写:
#include <stdio.h>
int main() {
printf("Hello World\n");
return 0;
}
然后如果我执行 ldd ./a.out
然后我得到这些库的列表:
linux-vdso.so.1 => (0x00007ffd6675c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2569866000)
/lib64/ld-linux-x86-64.so.2 (0x0000562b69162000)
链接器负责加载这些权利,那么谁负责终止此 ./a.out
可执行文件以隐式 dlclose()
这些库?
我没有 Kerrisk 的书,但如果你准确描述了它的内容,那么它们似乎有点简化。严格来说,每当进程终止时,函数 dlclose()
都会为其打开的每个共享库调用,但这样说是合理的,无论何时进程终止,其所有句柄打开共享库是关闭的。结果,操作系统识别出引用每个共享库的进程减少了,如果这使得任何共享库的引用计数为零,那么操作系统可能会选择将它们从内存中卸载。
dlclose()
所做的工作远不止于此。特别是,它会导致库中的任何析构函数运行。当进程通过从 main()
返回或通过调用 exit()
正常退出时,这些函数也会运行,但如果进程通过其他方式终止,则不会运行,例如调用_exit()
或响应接收信号。在正常退出的情况下,净效果可能与为每个打开的共享库调用 dlclose()
相同,但即便如此,也不一定通过实际调用 dlclose( )
。
最后,请注意虽然 dl*()
函数是由 POSIX 定义的,但动态/共享库的所有细节基本上都由实现自行决定。由于您询问了有关 Linux 的书籍,我引用了一些特定于 Linux 的详细信息。
我是一名优秀的程序员,十分优秀!