目前,我试图了解当共享库生成一个线程时会发生什么,该线程不会终止,然后卸载共享库。
如果父节点没有等待线程退出,线程会发生什么? 线程是否死亡或是否仍处于运行状态?
如果是,那么父母如何检测它何时被卸载并以某种方式终止该线程?
感谢您的帮助。
答案 0 :(得分:3)
我假设共享库是在运行时使用dlopen(3)动态加载的一些插件,稍后使用dlclose
显式卸载。
dlopen
和dlclose
函数在内部使用引用计数器,它们是mmap(2) - 用于dlopen
}和munmap
- ing(用于dlclose
)适当时ELF共享对象内的一些段(即当ref计数器越过0边界时)。
如果某个线程正在dlclose
- d共享库中运行某个函数,那么该函数的代码将变为munmap
- 并且只要您跳转(或返回)该函数,获得SIGBUS,SIGILL或SIGSEGV信号。
所以你不希望munmap
发生:因此你可以:
避免致电dlclose
;这在实践中非常有效(除非你有一个服务器程序),因为mmap
主要占用共享对象的文本只读段的地址空间。正如我的manydl.c所示,您可以在桌面上dlopen
数十万个共享对象,而不会达到严重限制。
或将RTLD_NODELETE
传递给dlopen
,要求其永不取消映射库
或者,使用一些工具(即destructor - 共享库中的属性函数)或约定(可能是atexit(3)?)来确保线程在dlclose
之前结束
答案 1 :(得分:0)
共享库被加载到进程中,因此生成的线程将在进程地址空间中运行。
如果没有注意到退出,线程将继续运行。当进程退出时,线程也将被终止。
由于共享库产生了线程,所以共享库最好还提供一个注意线程退出的函数,这样进程可以在卸载库之前调用函数退出线程。