您的位置:首页 > 运维架构 > Linux

Linux进程通信之共享内存

2016-08-23 13:30 519 查看
这里简介一下共享内存的编程的模型,其它细节以后有时间再补充

创建共享内存,得到一个ID(函数shmget)

把ID映射成虚拟地址/挂载 (函数shmat)

使用虚拟地址访问内核共享内存,可以使用任何内存函数函数与运算符号

卸载虚拟地址 (函数shmdt)

删除共享内存 ,函数shctl(修改,获取共享内存的属性)

这里看下几个函数

#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);


对于创建共享内存的进程来讲,这个函数返回共享内存的Id,而对于接收方进程来讲,它通过这个函数来获取共享内存的Id,而如何获取到相同的Id则是由第一个参数key来决定的,大概可以理解为,创建共享内存的时候,把传入的key和内存的Id关联起来,等到接收方传入相同的key的时候,便会返回相同的Id.而保证key相同的办法则可以通过ftok函数利用相同的目录来获取,这里不作详述。只需要知道,传入相同的key就可以获取共享内存的Id即可。

第二个参数size则是共享内存的大小

第三个参数需要注意一下,一般来讲,创建者进程,一般传入IPC_CREAT|IPC_EXCL|权限,而作为接收方,传入0即可,其他细节请查看手册。

调用成功则返回Id,否则返回-1

对接收方进程而言,最后一个参数传入0即可。

接着调用shmat来得到共享内存,进行读写。shmdt来进行卸载

#include <sys/types.h>
#include <sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

int shmdt(const void *shmaddr)


最后是shmctl

#include <sys/ipc.h>
#include <sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);


第一个参数是由shmget返回的Id

第二个参数cmd 则是选择工作的方式

IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中

IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内

IPC_RMID:删除这片共享内存

一般我们用来删除Id的话,传入IPC_RMID即可,接收方不需要删除共享内存

举个栗子

shmA.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <signal.h>

key_t key;
int shmId;
int* p;
int i=0;
void handle(int s){
if(s==SIGINT){
shmdt(p);
shmctl(shmId,IPC_RMID,0);
exit(0);
}

}

int main(){

signal(SIGINT,handle);
//1. create shared memory
//
key=ftok(".",255);
if(key==-1)printf("ftok error,%m\n"),exit(-1);
shmId=shmget(key,4,IPC_CREAT|IPC_EXCL|0666);
if(shmId==-1)printf("shmget error,%m\n"),exit(-1);
//2. attach shared memory
p=shmat(shmId,0,0);
if(p==(int*)-1)printf("shmat error,%m\n"),exit(-1);
//3. use virtual address operate data
while(1){
*p=i++;;
sleep(1);
}

//4. deattach shared memory
//5. control(delete shared memory)

return 0;
}


shmB.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <signal.h>

key_t key;
int shmId;

int *p;
void handle(int s){
if(s==SIGINT){
shmdt(p);
exit(0);
}
}

int main(){
signal(SIGINT,handle);
//1. create shared memory
key=ftok(".",255);
if(key==-1)printf("ftok error,%m\n"),exit(-1);
shmId=shmget(key,4,0);
if(shmId==-1)printf("shmget error,%m\n"),exit(-1);
//2. attach shared memory
p=shmat(shmId,0,0);
if(p==(int*)-1)printf("shmat error,%m\n"),exit(-1);
//3. use virtual address operate data
while(1){
sleep(1);
printf("num=%d\n",*p);
}

//4. deattach shared memory
shmdt(p);
//5. control(delete shared memory)
//

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux