我们的应用程序依赖于外部第三方提供的配置(包括自定义驱动/决策功能),可作为 .so 文件加载。
独立地,它使用一块共享内存与外部 CGI 模块协作,其中几乎所有易失性状态都被保留,以便外部模块可以读取它并在适用的情况下修改它。
问题是 CGI 模块也需要来自 .so 的大量永久配置数据,并且主应用程序在两个内存区域之间执行大量完全不必要的复制以使数据可用。这个想法是将整个共享对象加载到共享内存中,并使其直接可供 CGI 使用。问题是:怎么办?
- dlopen 和 dlsym 不提供任何用于分配 SO 文件加载位置的工具。
- 我们尝试了 shmat()。它似乎只有在某些外部 CGI 实际尝试访问共享内存时才起作用。然后,所指向的区域就显得私密,就好像它从未被共享过一样。也许我们做错了什么?
- 在每个需要它的脚本中加载 .so 是毫无疑问的。该结构的庞大规模,与调用频率相关(某些脚本每秒调用一次以生成实时更新),而且这是一个嵌入式应用程序,因此无法使用。
- 简单地 memcpy() 将 .so 转换为 shm 也不好 - 某些结构和所有函数都通过指针互连。
使用共享内存时首先要记住的是,相同的物理内存很可能作为不同的地址映射到两个进程的虚拟地址空间中。这意味着如果在数据结构中的任何地方使用指针,它们都会导致问题。一切都必须通过索引或偏移量才能正常工作。要使用共享内存,您必须清除代码中的所有指针。
加载 .so 文件时,仅加载 .so 文件代码的一份副本(因此称为共享对象)。
fork
也可能是你在这里的朋友。大多数现代操作系统都实现写时复制语义。这意味着当您fork
,当一个进程写入给定的数据段时,您的数据段仅被复制到单独的物理内存中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)