纸上得来终觉浅,这句话一点不假,动态库的知识在看《程序员的自我修养》这本书已经了解了。但是到实际项目遇到问题
却没往这方面去考虑。浪费了半天时间。
问题是这样的:我有个模块编译成一个so库供其他程序使用。比如A,B都需要链接lib.so。lib.so里面有个全局指针p,当A程序调用lib.so的函数启动lib的功能后这个p指针就被赋值了。然后B程序启动,但奇怪的是在B程序里面调用lib.so库函数去get p指针的时得到的却是未初始化的值。导致B程序无法运行,然后就郁闷了半天。明明A已经正常启动把p赋值了,为什么p还是NULL呢?原来是A和B只是共有Lib.so的代码段,但是数据段A和B都有各自的一份是不共享的。为此我做了一个实验。
(1)lib.c和lib.h
#include <stdio.h>
#include "lib.h"
static int a = 0;
void set(int v)
{
a = v;
printf("a = %d\n", a);
return;
}
void get()
{
printf("a = %d\n", a);
}
void set(int v);
void get();
将Lib.c编译成一个so库:
gcc -fPIC -shared -o lib.so lib.c
(2)应用程序1: program1.c
#include "lib.h"
#include <time.h>
void main()
{
int cnt = 0;
while(1){
set(cnt++);
usleep(1000000);
}
return;
}
功能:每隔1秒钟去修改Lib.so的a的值
(3)应用程序2: program2.c
#include "lib.h"
#include <time.h>
void main()
{
while(1){
get();
usleep(500000);
}
return;
}
功能:每隔500ms去取lib.so里a的值
编译:
gcc -o program1 program1.c ./lib.so
gcc -o program2 program2.c ./lib.so
运行:
./program1 &
./program2
结果:
a = 1
a = 2
./a = 3
programa = 4
2
a = 0
a = 5
a = 0
a = 0
a = 6
a = 0
a = 0
a = 7
a = 0
a = 0
a = 8
a = 0
a = 0
a = 9
a = 0
a = 0
a = 10
a = 0
a = 0
a = 11
a = 0
a = 0
a = 12
从结果可以看出:program1一直在修改a的值,但是program2取得的值一直是0。
这是不同进程的情况。
又做了一个实验,对于同一个进程中的不同的两个线程结果又是怎样呢?
代码如下:
#include "lib.h"
#include <time.h>
#include <pthread.h>
void* thread1(void* data)
{
int cnt = 0;
while(1){
printf("thread1 set...\n");
set(cnt++);
usleep(1000000);
}
return NULL;
}
void* thread2(void* data)
{
while(1){
printf("thread2 get...\n");
get();
usleep(500000);
}
}
void main()
{
pthread_t thread_id;
pthread_create(&thread_id, NULL, &thread1, NULL);
pthread_create(&thread_id, NULL, &thread2, NULL);
while(1){
usleep(10000000);
}
return;
}
就是把program1和2变为两个线程。
运行结果如下:
thread1 set...
a = 0
thread2 get...
a = 0
thread2 get...
a = 0
thread1 set...
a = 1
thread2 get...
a = 1
thread2 get...
a = 1
thread1 set...
a = 2
thread2 get...
a = 2
thread2 get...
a = 2
thread1 set...
a = 3
thread2 get...
a = 3
thread2 get...
a = 3
thread1 set...
a = 4
thread2 get...
a = 4
thread2 get...
a = 4
可以看出对于两个线程,so的数据段是共享的。
特此记录下。