Posted inLinux/Unix,编程 10 条留言

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

1
2
3
4
5
[c] view plain copy
  1. "color:#339933">#ifndef TEST_SHARE__H  
  2. "color:#339933">#define TEST_SHARE__H  
  3. "color:#000000; font-weight:bold">extern "color:#993333">void set_global"color:#009900">("color:#993333">int i"color:#009900">)"color:#339933">;  
  4. "color:#000000; font-weight:bold">extern "color:#993333">int get_global"color:#009900">("color:#009900">)"color:#339933">;  
  5. "color:#339933">#endif  

testshare.c

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

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

1
[c] view plain copy
  1. gcc "color:#339933">-fPIC "color:#339933">-shared testshare."color:#202020">c "color:#339933">-o libtestshare."color:#202020">so  

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

1
2
3
4
5
6
7
8
9
10
[c] view plain copy
  1. "color:#339933">#include "testshare.h"  
  2. "color:#339933">#include   
  3. "color:#339933">#include   
  4. "color:#993333">int main"color:#009900">("color:#009900">)  
  5. "color:#009900">{  
  6.     "http://www.opengroup.org/onlinepubs/009695399/functions/printf.html">"color:#000066">printf"color:#009900">("color:#ff0000">"%dcolor:#000099; font-weight:bold">\n""color:#339933">, get_global"color:#009900">("color:#009900">)"color:#009900">)"color:#339933">;  
  7.     set_global"color:#009900">("color:#0000dd">100"color:#009900">)"color:#339933">;  
  8.     "http://www.opengroup.org/onlinepubs/009695399/functions/printf.html">"color:#000066">printf"color:#009900">("color:#ff0000">"%dcolor:#000099; font-weight:bold">\n""color:#339933">, get_global"color:#009900">("color:#009900">)"color:#009900">)"color:#339933">;  
  9.     sleep"color:#009900">("color:#0000dd">10000"color:#009900">)"color:#339933">;  
  10. "color:#009900">}  

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

1
[c] view plain copy
  1. gcc testshare_main1."color:#202020">c "color:#339933">-L. "color:#339933">-ltestshare "color:#339933">-o main1  

执行程序:

1
[c] view plain copy
  1. LD_LIBRARY_PATH"color:#339933">=. ."color:#339933">/main1  

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

1
2
[c] view plain copy
  1. "color:#0000dd">1000  
  2. "color:#0000dd">100  

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

November 28, 2010