动态共享库加载到内存中,怎样才能保证只有一份副本

这几天一直在看关于动态共享库的知识,但看到一个地方,就不懂了,在网上搜索了一下!也没有找到答案!希望有哪位高手,帮小弟解答一下,小弟不胜感激!
问题:动态共享库,顾名思义,可以在多个进程间,进行共享!在系统中只保存一份副本,现在假设Process A已经将Lib A Load到物理内存,但当同样共享Lib A的Process B开始运行时,它是如何知道Lib A已经被加载到内存中,且如何找到这块物理内存?

1个回答

13年的老问题了,今天偶然看到这个问题也引起了我的思考,下面给出我的理解:

1、linux中使用struc link_map结构体来描述一个被装载进内存的动态库,比如Process A 将Lib A Load到物理内存,那么在加载进内存的过程中
就会构建这样的一个动态库描述符link_map

2、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

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问