星空网 > 软件开发 > 操作系统

了解动态链接(三)—— 共享模块的全局变量问题

假设module.c中引用了一个共享模块中定义的全局变量global:

1 extern int global;2 3 int foo() {4   global = 1;5 }

编译器无法确定变量global的定义是在模块内部还是外部。假设module.c是可执行文件的一个源文件,可执行程序不是PIC的,不会进行重定位。链接器会在.bss段创建一个global变量的副本,这样造成同一个变量同时存在于多个位置。问题的解决办法是让所有对变量global的访问都指向可执行文件中的那个副本。

ELF共享库在编译时,默认把所有全局变量都当作是定义在其他模块中,通过GOT表实现外部访问。当共享模块被装载时,如果某个全局变量在可执行文件中拥有副本,动态链接器就把GOT表中的相应地址指向该副本。如果该变量在可执行文件中没有副本,那么GOT表中的相应地址就指向模块内部的该变量副本。

假设libx.so中定义了一个全局变量G,进程A和B都使用libx.so。那么当libx.so被两个进程加载时,它的数据段在每个进程中都有独立的副本,所以进程A和B访问的都是自己进程中的那个全局变量G的副本,相互之间没有影响。但如果是同一个进程的线程A和B,则他们访问的是同一个副本。

而有时希望同一个进程中的不同线程,也访问全局变量的不同副本,这样可以避免线程之间对全局变量的干扰,或者避免做线程同步。这可以通过线程私有存储(Thread Local Storage, TLS)来实现。在Android系统中,TLS是借助协处理器来实现的,在Linker和getpid等函数的实现中都能看到有关TLS的代码。

有时也会希望多个进程共享同一个全局变量的副本,借此实现进程间通信。记得以前写Windows DLL时,有“共享数据段”的概念就是实现这个的。

学习资料: 《程序员的自我修养——链接、装载和库》




原标题:了解动态链接(三)—— 共享模块的全局变量问题

关键词:

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

Play:https://www.ikjzd.com/w/1573203616815898625
plentymarkets:https://www.ikjzd.com/w/1573203618946260994
PLIN:https://www.ikjzd.com/w/1573203619747373057
AllSale比柚:https://www.ikjzd.com/w/1573203622276882433
Pngme:https://www.ikjzd.com/w/1573203624138809346
亚马逊行动计划书:https://www.ikjzd.com/w/1573203625129009153
春季热卖单品!空气净化器单周销售额近三十万!:https://www.kjdsnews.com/a/1836547.html
春季热卖单品!空气净化器单周销售额近三十万!:https://www.goluckyvip.com/news/188215.html
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流