Linux中线程如何共享内存?——探析内存共享机制(linux线程共享内存)
Linux中线程共享内存具备非常灵活的机制和操作方法,它有三种基本方式可以实现:mmap(内存映射)、shmget(共享内存)和shmat(共享内存连接)。其中,执行进程的线程主要通过mmap(内存映射)和shmget(共享内存)方式共享内存,但是必须使用shmat(共享内存连接)来检测共享内存是否存在和访问共享内存中的数据。
1. 使用mmap(内存映射)来实现线程间共享内存
mmap() 函数允许将一个文件或者其它内存对象映射到进程的地址空间。通过 mmap 函数可以映射一块共享内存块,并将该内存块映射到当前进程的虚拟内存地址上,各个线程可通过具体的地址进行访问和共享。
代码示例:
//mmap.c
#include
#include
#include
#include
#include
#include
//结构体描述struct STU{
int id; char name[20];
}stu;
int main(){ int fd_r;
int fd_w; //只读打开文件映射操作
fd_r = open("stu.txt", O_RDONLY); //只写打开文件映射操作
fd_w = open("stu.txt", O_RDWR); int length = sizeof(stu);
//是进程的虚拟内存空间映射一个文件或者是其他的内存区域 struct STU *p = (struct STU*)mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd_w, 0);
if(p == MAP_FAILED){ perror("mmap error");
exit(-1); }
// 线程1读取STU结构体中的信息 printf("id: %d\n", p->id);
printf("name: %s\n", p->name); //线程2修改STU结构体中的信息
p->id = 100; strcpy(p->name,"Lucy");
// 映射取消 munmap(p, length);
close(fd_r); close(fd_w);
return 0;}
2. 使用shmget(共享内存)来实现线程间共享内存
shmget() 用于申请或者创建一块共享内存,可以指定内存大小,并将该共享内存分配到指定的内存地址,可以让其它进程使用此内存区域。
代码示例:
//shmget.c
#include
#include
#include
#include
int main() {
key_t key = ftok("fdoc",65);//生成共享内存的键值
// 共享内存的识别值 shmid int shmid = shmget(key,1024,0666|IPC_CREAT); //shmget函数返回共享内存标志符
//将共享内存连接到当前进程的地址空间
char *str = (char*)shmat(shmid,(void*)0,0);
printf("Write Data : "); //从键盘输入数据
gets(str);
//断开此段共享内存 shmdt(str);
//控制共享内存
shmctl(shmid,IPC_RMID,NULL);
return 0; }
3. 使用shmat(共享内存连接)来实现线程间共享内存
shmat() 用于将共享内存连接到当前进程的地址空间,所有的线程都可以使用共享内存进行数据交换,同时还可以实现线程间的数据同步。
代码示例:
//shmat.c
#include
#include
#include
#include
int main(){
int shmid; // 生成共享内存的key(键值)
// ftok用来生成键值,它把一个文件名和一个数字转换成一个key_t类型键值 key_t key = ftok("shmfile",65);
// 获得共享内存,如果没有则创建一块;IPC_CREAT是在操作系统分配stu