目录
一、共享内存概念:
二、获取或申请共享内存
三、映射共享内存到进程的虚拟空间
四、解除映射
五、删除共享内存:
linux内核为多个进程专门提供了一块内存空间,用于多个进程的通信,这块空间是一块公共内存空间
进程只需要将这块内存空间,映射到自己的虚拟内存空间,直接操作自己的内存空间,就相当于操作这块公共内存空间。
我们把这块公共的内存空间称为共享内存。
共享内存特征:
1》通信的效率最高
2》多个进程用共享内存通信时,需要同步。
#include
#include
int shmget(key_t key, size_t size, int shmflg);
//参数1 ----- key
//参数2 ----- 共享内存的大小
//参数3 ----- 标签:表示权限:IPC_CREAT | 0666
//返回值----- 成功:共享内存的ID,失败:-1 例如:
int main(void)
{
key_t key;
int shm_id;
if((key = ftok("./",0xb)) < 0)
perr("ftok");
if((shm_id = shmget(key,SHMSIZE,IPC_CREAT|0666)) < 0)
perr("shmget");
return 0;
}
void *shmat(int shmid, const void *shmaddr, int shmflg);
//参数1 ---- 共享内存ID
//参数2 ---- 指定映射到进程虚拟空间的某个地址,但是一般为:NULL,让系统自动映射到一个可用的地址
//参数3 ---- 权限,一般为0,表示可读可写
//返回值 ----- 成功:返回映射的虚拟空间的起始地址,失败:-1
int shmdt(const void *shmaddr);
//参数 ------ 必须是shmat返回的起始地址
//返回值 ---- 成功:0,失败:-1
例如:
#include "shm.h"
int main(void)
{
key_t key;
int shm_id;
char * buf;
//获取key
if((key = ftok("./",0xb)) < 0)
perr("ftok");
//创建或获取共享内存
if((shm_id = shmget(key,SHMSIZE,IPC_CREAT|0666)) < 0)
perr("shmget");
//映射共享内存到进程的虚拟空间
if((buf = shmat(shm_id,NULL,0)) < 0)
perr("shmat");
while(1){
fgets(buf,SHMSIZE,stdin);
if(!strncmp(buf,"quit",4))
break;
}
if(shmdt(buf) < 0)
perr("shmdt");
return 0;
}
#include "shm.h"
int main(void)
{
key_t key;
int shm_id;
char * buf;
//获取key
if((key = ftok("./",0xb)) < 0)
perr("ftok");
//创建或获取共享内存
if((shm_id = shmget(key,SHMSIZE,IPC_CREAT|0666)) < 0)
perr("shmget");
//映射共享内存到进程的虚拟空间
if((buf = shmat(shm_id,NULL,0)) < 0)
perr("shmat");
while(1){
if(!strncmp(buf,"quit",4))//比较前4个字节
break;
printf("%s",buf);
sleep(1);
}
if(shmdt(buf) < 0)
perr("shmdt");
return 0;
}
#include
#include
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
//参数1 ------ 共享内存ID
//参数2 ------ 功能:
IPC_STAT -----获取共享内存的信息
IPC_SET -----设置共享内存信息
IPC_RMID -----删除共享内存
//参数3 ------- 结构体struct shmid_ds 指针
struct ipc_perm {
key_t __key; /* Key supplied to shmget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions + SHM_DEST and
SHM_LOCKED flags */
unsigned short __seq; /* Sequence number */
};
//返回值 ----成功:0,失败:-1
例如:
int main(int argc,char **argv)
{
int shm_id;
if(argc != 2){
fprintf(stderr,"Usage: %s \n",argv[0]);
exit(1);
}
shm_id = atoi(argv[1]);
if(shmctl(shm_id,IPC_RMID,NULL) < 0)
perr("shmctl");
return 0;
}