栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

程序员应了解的那些事(108)C++对象模型:效率有了,弹性呢?

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

程序员应了解的那些事(108)C++对象模型:效率有了,弹性呢?

        摘自深度探索C++对象模型第七章:


7.4    效率有了,弹性呢?

        传统的C++对象模型提供有效率的执行期支持,这份效率再加上与C之间的兼容性,造成了C++的广泛被接受度。然而在某些领域,像是动态共享函数库(dynamically shared libraries),共享内存(shared memory),以及分布式对象(distributed object)方面,这个对象模型的弹性还是不够。

动态共享函数库 (Dynamic Shared Libraries)

        理想中,一个动态链接的shared library应该像"突然造访"一样。也就是说,当应用程序下一次执行时,会透明化地取用新的library版本。新的版本不应该对旧的应用程序产生侵略性,应用程序也不应该需要为此重新建造一次。但是,在目前的C++对象模型中如果新版的library中的 class object布局有所变更,上述的"library无侵略性"的说法就有待商榷了。这是 因为 class 的大小以及其每一个直接(或继承而来)的members的偏移量(offset)都在编译时期就已经固定(虚拟继承的members除外)。这虽然带来效率,却在二进制层面影响了弹性:如果object布局改变,应用程序就必须重新编译。

共享内存 (Shared Memory) 概念:

        共享内存(Shared Memory)就是允许多个进程访问同一个内存空间,是在多个进程之间共享和传递数据最高效的方式。操作系统将不同进程之间共享内存安排为同一段物理内存,进程可以将共享内存连接到它们自己的地址空间中,如果某个进程修改了共享内存中的数据,其它的进程读到的数据也将会改变。     

问题:

        当一个shared library被加载,它在内存中的位置由runtime linker决定,一般而言与执行中的进程(process)无关。然而在C++对象模型中,当一个动态的shared library支持一个 class object,其中含有 virtual functions(被放在shared memory中),上述说法便不正确。

        问题并不在于"将该object放置于shared memory中"的那个进程,而在于"想要经由这个shared object附着并调用一个virtual function"的第二个或更后继的进程。除非 dynamic shared library被放置于完全相同的内存位置上,就像当初加载这个shared object的进程一样。否则 virtual function会死的很难看,可能的错误包括segment fault或bus error。原因在于每一个 virtual function在 virtual table中的位置已经被固定了。

总结:

        如果程序使用到动态库里的一个对象,而该对象有一个虚表指针,由于每个进程所对应的动态库地址是不一样的,会导致两个进程使用同一个共享内存,同一个对象,相同的虚表指针,但是指向的地址,内容,却大大的不太,导致问题。

解决:

         目前的解决办法是属于程序层面,程序员必须保证让跨越进程的shared libraries有相同的坐落地址(在SGI中,使用者可以根据所谓的so-location文件,指定每一个shared library的精确位置)。至于编译系统层面上的解决办法,势必要牺牲原本的 virtual table实现模型所带来的高效率。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1004506.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号