无法访问共享对象文件中的共享指针问题排查
问题:共享库变量无法跨进程共享?
我有三段代码:main.c、main2.c和sharedlib.c,代码及运行现象如下:
main.c 代码
#include <stdio.h> #include <sys/types.h> #include <stdlib.h> #include <sys/mman.h> #include <unistd.h> #include <string.h> extern char* sharedPtr; int main(void) { sharedPtr = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); fprintf(stdout, "addr = 0x%x\n", sharedPtr); sleep(10); munmap(sharedPtr, 1024); return 0; }
main2.c 代码
#include <stdio.h> extern char* sharedPtr; int main(void) { fprintf(stdout, "0x%x\n", (void*)sharedPtr); return 0; }
sharedlib.c 代码
char* sharedPtr;
编译命令
gcc main.c -o main -L${PWD} -lsharedlib gcc main2.c -o main2 -L${PWD} -lsharedlib gcc sharedlib.c -o libsharedlib.so -shared -fPIC
运行现象
运行main程序时,它会打印地址并休眠10秒:
addr = 0xb6f77000
在这10秒内运行main2,输出却是:
0x0
疑问
这是为什么?main.c仍在运行,它应该已设置了共享库中的变量,但main2却看不到指针的值?
编辑补充:将指针替换为随机整数,结果完全相同,即main2无法读取main写入的值,仍输出0,说明该问题与mmap的使用无关。
原因分析
这是因为每个进程都有独立的虚拟地址空间,即使链接了同一个共享库,共享库中的全局变量在每个进程里都会生成一份独立的私有副本,而非真正的跨进程共享。
默认情况下,共享库的全局变量属于进程私有数据:main进程里的sharedPtr和main2进程里的sharedPtr是两个完全独立的内存位置,修改其中一个不会影响另一个。
实现真正跨进程共享的方法
如果需要让变量在多个进程间真正共享,必须借助进程间共享内存机制,常见方案有:
- 使用
shm_open配合mmap创建共享内存对象,映射到各进程地址空间 - 使用SysV共享内存接口(
shmget、shmat等) - 通过编译属性+链接脚本,将共享库变量标记为共享内存段
举个简单修改示例,修改sharedlib.c实现真正共享:
#include <sys/mman.h> #include <fcntl.h> #include <unistd.h> // 指向共享内存区域的指针 char* sharedPtr; // 进程启动时初始化共享内存 __attribute__((constructor)) void init_shared_var() { int fd = shm_open("/my_shared_ptr", O_CREAT | O_RDWR, 0666); ftruncate(fd, sizeof(char*)); sharedPtr = mmap(NULL, sizeof(char*), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); close(fd); } // 进程退出时清理共享内存 __attribute__((destructor)) void cleanup_shared_var() { munmap(sharedPtr, sizeof(char*)); shm_unlink("/my_shared_ptr"); }
修改后,main和main2访问的是同一块共享内存中的数据,main2就能读取到main设置的值了。
内容的提问来源于stack exchange,提问作者ohiliouh
相关产品推荐
相关产品推荐

