Linux C中动态链接库的全局变量问题

如果一个共享对象libtest.so中定义了一个全局变量G,而进程A和进程B都使用了libtest.so, 那么当进程A改变这个全局变量G的值时,进程B中的G会受到影响吗?

古人云:实践出真知...

/*
 * =====================================================================================
 *
 *       Filename:  lib.h
 * =====================================================================================
 */
#ifndef __LIB_H__
#define __LIB_H__

void foobar();

#endif

 

/*
 * =====================================================================================
 *
 *       Filename:  lib.c
 *
 * =====================================================================================
 */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "lib.h"

int number = 0;

void foobar()
{
    printf("PID:%d number: %d\n",getpid(),number);
    number++;
    printf("PID:%d number: %d\n",getpid(),number);
}

/*
 * =====================================================================================
 *
 *       Filename:  pro1.c
 *
 * =====================================================================================
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "lib.h"

int main(int argc, char * argv[])
{
    sleep(10);
    foobar();
    
    return 0;
}

 

执行编译:

Linux C中动态链接库的全局变量问题

运行:

Linux C中动态链接库的全局变量问题

由程序运行结果可知,动态库中全局变量并未受到改变,也就是动态库中的全局变量在不同进程链接时是相互独立的!

 

事实上,动态库的出现的历史原因是运行不同程序时减少相同目标文件的副本,从而达到减少内存使用的母的。最典型的就是linux中常用的C语言运行库glibc了。但其实这还不够,如果共享库中的指令部分无法在多个进程之间共享,那么失去了动态库节省内存的一大优势。所以就有了地址无关代码(PIC, Position-independent Code)的技术(这样是不是想起了gcc编译动态库中-fPIC参数了呢)。当libtest.so被两个进程加载时,它的数据段部分在每个进程中都有独立的副本,从这个角度看,共享对象中的全局变量实际上和定义在程序内部的全局变量没什么区别。