Posted inLinux/Unix,编程 10 条留言

今天和同学在BBS上讨论有关动态链接库中的全局变量的问题。如果某动态库中有一个全局变量,程序a使用的这个动态库,程序b也使用了这个动态库,那么程序a和b中的全局变量是一个吗?也就是说,进程间使用动态库时,共享全局变量吗?答题是:是一个,共享,但写时拷贝,给程序员的感觉是:不共享。谢谢WWF的说明。
看看下面的测试:
testshare.h

1
2
3
4
5
  1. <span style="color:#339933">#ifndef TEST_SHARE__H</span>  
  2. <span style="color:#339933">#define TEST_SHARE__H</span>  
  3. <span style="color:#000000; font-weight:bold">extern</span> <span style="color:#993333">void</span> set_global<span style="color:#009900">(</span><span style="color:#993333">int</span> i<span style="color:#009900">)</span><span style="color:#339933">;</span>  
  4. <span style="color:#000000; font-weight:bold">extern</span> <span style="color:#993333">int</span> get_global<span style="color:#009900">(</span><span style="color:#009900">)</span><span style="color:#339933">;</span>  
  5. <span style="color:#339933">#endif</span>  

testshare.c

1
2
3
4
5
6
7
8
9
10
11
  1. <span style="color:#339933">#include "testshare.h"</span>  
  2. <span style="color:#993333">int</span> global_i <span style="color:#339933">=</span> <span style="color:#0000dd">1000</span><span style="color:#339933">;</span>  
  3. <span style="color:#993333">void</span> set_global<span style="color:#009900">(</span><span style="color:#993333">int</span> i<span style="color:#009900">)</span>  
  4. <span style="color:#009900">{</span>  
  5.     global_i <span style="color:#339933">=</span> i<span style="color:#339933">;</span>  
  6. <span style="color:#009900">}</span>  
  7.    
  8. <span style="color:#993333">int</span> get_global<span style="color:#009900">(</span><span style="color:#009900">)</span>  
  9. <span style="color:#009900">{</span>  
  10.     <span style="color:#b1b100">return</span> global_i<span style="color:#339933">;</span>  
  11. <span style="color:#009900">}</span>  

上面的两个程序片断很简单,其中testshare.h中声明了两个函数,testshare.c中实现了这两个函数,而且定义了一个全局变量。接下来,把testshare.c编译成动态库

1
  1. gcc <span style="color:#339933">-</span>fPIC <span style="color:#339933">-</span>shared testshare.<span style="color:#202020">c</span> <span style="color:#339933">-</span>o libtestshare.<span style="color:#202020">so</span>  

下面程序testshare_main1.c,使用动态库libtestshare.so,

1
2
3
4
5
6
7
8
9
10
  1. <span style="color:#339933">#include "testshare.h"</span>  
  2. <span style="color:#339933">#include <stdio.h></span>  
  3. <span style="color:#339933">#include <unistd.h></span>  
  4. <span style="color:#993333">int</span> main<span style="color:#009900">(</span><span style="color:#009900">)</span>  
  5. <span style="color:#009900">{</span>  
  6.     <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color:#000066">printf</span></a><span style="color:#009900">(</span><span style="color:#ff0000">"%d<span style="color:#000099; font-weight:bold">\n</span>"</span><span style="color:#339933">,</span> get_global<span style="color:#009900">(</span><span style="color:#009900">)</span><span style="color:#009900">)</span><span style="color:#339933">;</span>  
  7.     set_global<span style="color:#009900">(</span><span style="color:#0000dd">100</span><span style="color:#009900">)</span><span style="color:#339933">;</span>  
  8.     <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color:#000066">printf</span></a><span style="color:#009900">(</span><span style="color:#ff0000">"%d<span style="color:#000099; font-weight:bold">\n</span>"</span><span style="color:#339933">,</span> get_global<span style="color:#009900">(</span><span style="color:#009900">)</span><span style="color:#009900">)</span><span style="color:#339933">;</span>  
  9.     sleep<span style="color:#009900">(</span><span style="color:#0000dd">10000</span><span style="color:#009900">)</span><span style="color:#339933">;</span>  
  10. <span style="color:#009900">}</span>  

用下面的命令编译上面的程序并执行:

1
  1. gcc testshare_main1.<span style="color:#202020">c</span> <span style="color:#339933">-</span>L. <span style="color:#339933">-</span>ltestshare <span style="color:#339933">-</span>o main1  

执行程序:

1
  1. LD_LIBRARY_PATH<span style="color:#339933">=</span>. .<span style="color:#339933">/</span>main1  

执行的时候,我们在两个终端里先后分次执行程序,发现程序都输出

1
2
  1. <span style="color:#0000dd">1000</span>  
  2. <span style="color:#0000dd">100</span>  

显然,后执行的程序并没有受到先执行的程序的影响。由此可见,不同的进程并不共享相同动态库中的全局变量
另外,如果有两个动态库中有同名的全局变量,在同时使用这两个动态库时,链接器中链接写在前面动态库中的全局变量写在前面指的是编译命令中库排列在前的。

November 28, 2010