c - 当进程 fork 时,共享库 .so 是否仍在地址空间中?构造函数会再次执行吗?

标签 c linux multithreading process fork

当进程 fork 时,子进程的地址空间中是否会有自定义的共享库(.so 文件)?

如果是这样,共享库的地址与其父进程的地址相同还是不同(由于 ASLR)?

在主函数__attribute__((constructor))构造函数之前运行的函数是否会在所有子进程中再次执行?线程呢?

最佳答案

是的, child 会保留 parent 的映射。通常,Linux 的虚拟内存系统实际上会在两个进程之间共享页面,直到其中一个尝试写入新数据为止。届时,将制作一个副本,每个进程将拥有自己唯一的版本 - 在不同的物理地址但保留相同的虚拟地址。这被称为“写时复制”,与不支持此功能的系统相比具有显着的效率和资源优势,尤其是运行频繁 fork 的代码。

地址空间布局随机化 (ASLR) 无法应用于已分配虚拟地址的库或对象,因为这样做会破坏代码中任何位置的任何指针 - 这是运行非托管代码的系统无法做到的。对解释了解不够。

由于之前构造的所有对象都已经存在于内存中,构造函数不会因为fork而再次被调用。任何因为被独特修改而需要复制的对象都由 VM 系统在幕后无形地完成了这项工作——它们并不真正知道它们正在被克隆,而且你很可能最终得到一对对象,其中实现的一部分继续共享具有相同内容的物理页面,而另一部分已无形地分为不同的物理页面,每个进程具有不同的内容。

您还询问了线程,这是一个让事情变得复杂的领域。通常,只有调用 fork() 的线程才会以事件形式存在于子线程中(尽管属于其他线程的数据将存在于共享映射中,因为无法知道什么可能与 fork 线程共享)。如果您需要尝试 fork 多线程程序,则需要查看线程实现的文档。对于Linux上常见的pthreads实现,特别注意pthread_atfork()

关于c - 当进程 fork 时,共享库 .so 是否仍在地址空间中?构造函数会再次执行吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29735452/

相关文章:

c - 简单地将指针传递给另一个函数失败

c++ - 谜:将GNU C标签指针转换为函数指针,并使用内联asm将ret放入该 block 中。 block 被优化掉了吗?

c - C语言中如何判断用户输入的数字是否为1位或以上?

java - 为什么我的多线程排序算法不比我的单线程归并排序快

使用 kbhit 的 Python 套接字线程

c - C 中指针数组的段错误

c - 从 Linux 上的根程序获得对 tty 设备的独占访问权

linux - 如何在 linux rpl 中跳过输出?

linux - wget redownload 从开始未完成的文件下载并继续下载剩余的文件

multithreading - 加入第一个完成的线程?