这几天一直在看关于动态共享库的知识,但看到一个地方,就不懂了,在网上搜索了一下!也没有找到答案!希望有哪位高手,帮小弟解答一下,小弟不胜感激!
问题:动态共享库,顾名思义,可以在多个进程间,进行共享!在系统中只保存一份副本,现在假设Process A已经将Lib A Load到物理内存,但当同样共享Lib A的Process B开始运行时,它是如何知道Lib A已经被加载到内存中,且如何找到这块物理内存?
动态共享库加载到内存中,怎样才能保证只有一份副本
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
1条回答 默认 最新
- SweeNeil 2018-11-22 07:40关注
13年的老问题了,今天偶然看到这个问题也引起了我的思考,下面给出我的理解:
1、linux中使用struc link_map结构体来描述一个被装载进内存的动态库,比如Process A 将Lib A Load到物理内存,那么在加载进内存的过程中
就会构建这样的一个动态库描述符link_map2、Process B共享了这个Lib A,并且开始运行了,会在已存在的link_map链表中遍历,查看这个Lib A是否被加载进来了:
/* Look for this name among those already loaded. 在已经加载的名称中查找此名称。*/ for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next) { /* If the requested name matches the soname of a loaded object, use that object. Elide this check for names that have not yet been opened. 如果请求的名称与加载的对象的soname匹配,请使用该对象。 请检查尚未打开的名称。*/ if (__builtin_expect (l->l_faked, 0) != 0 || __builtin_expect (l->l_removed, 0) != 0) continue; if (!_dl_name_match_p (name, l)) { const char *soname; if (__builtin_expect (l->l_soname_added, 1) || l->l_info[DT_SONAME] == NULL) continue; soname = ((const char *) D_PTR (l, l_info[DT_STRTAB]) + l->l_info[DT_SONAME]->d_un.d_val); if (strcmp (name, soname) != 0) continue; /* We have a match on a new name -- cache it. 我们有一个新名称匹配 - 缓存它。*/ add_name_to_object (l, soname); l->l_soname_added = 1; } /* We have a match. */ return l; }
如果被加载进来了就直接返回这个link_map给链接器,由链接器来进行重定位之类的操作。
3、如何找到这块物理内存
在link_map中有如下字段
dev_t l_dev;
ino64_t l_ino;st_ino,这是物理文件在内存中编号,
设备号st_dev解决 无用评论 打赏 举报