Linux之共享内存
Linux之共享内存
共享内存:
申请一块内存区域,两个进程都可以访问,利用该区域实现进程之间传递信息。
需要将共享的内存区域映射到自己的地址空间;
进程读写映射的空间相当于读写内存空间。
共享内存的操作机制没有阻塞机制;同步控制比较空难。
使用结束后需要解除映射,释放共享内存
实现步骤:
申请共享内存:
头文件:sys/shm.h sys/ipc.h
int shmget(key_t key,size_t size,int shmflg);
函数功能:创建一个共享内存对象并返回共享内存标识符;如已存在共享内存则返回内存标识符。
参数:key:会建立新的共享内存对象,是一个大于0的32位整数,通常要求此值来源于ftok
返回的IPC键值;
size:大于0的整数;表示新建内存的大小,以字节为单位;
shmflg:0,共享内存标识符,若不存在则函数会报错;
IPC_CREAT:当shmflg&IPC_CREAT为真时,如果内核中不存在键值与key相
等的共享内存,则新建一个共享内存;如果存在这样的共享内存,返回此共享内
存的标识符;
IPC_CREAT|IPC_EXCL:如果内核中不存在键值与key相等的共享内存,则新建
一个共享内存;如果存在这样的共享内存则报错。
使用时需要与IPC对象存取权限(如0600)进行|运算来确定信号量集的存取权限。
成功:返回共享内存的标识符;失败:返回-1,错误原因存于error中。
映射共享内存:
void *shmat(int shmid,const void *shmaddr,int shmflg);
功能:连接共享内存标识符为shmid的共享内存,连接成功后把共享内存区映射到调用进程的
地址空间,随后可以像访问本地空间一样进行访问;
参数:shmid:共享内存标识符;
shmaddr:指定共享内存出现在进程内存地址的什么位置,直接指定为NULL可以让内
核自己确定一个合适的地址位置;
shmflg:SHM_RDONLY:为只读模式,其他为读写模式。可以直接写0。
返回值:成功:附加好的共享内存地址;出错:返回-1,错误原因存于error中。
解除映射:
int shmaddr(const void *shmaddr);
功能:与shmat函数相反,是用来断开与共享内存附加点的地址,禁止本进程访问此片共享内
存,本函数调用并不删除所指定的共享内存区,而只是将先前用shmat函数(attach)
好的共享内存脱离(detach)目前的进程。Int shmdt(const void *shmaddr);
参数:shmaddr:连接的共享内存的起始地址
返回值:成功:返回0;出错:返回-1,错误原因存于error中
释放:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:释放共享内存;
参数:1.shmid:共享内存标识符;
2.cmd:IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf
中;
IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode
复制到共享内存的shmid_ds结构内;
IPC_RMID:删除这片共享内存。
3.buf:共享内存管理结构体。具体说明参见共享内存内核结构定义部分。
成功:返回0;出错:返回-1,错误原因存于error中。
创建共享内存,往共享内存中写数据:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int shmid = 0;
char *addr = NULL;
key_t key = 0;
int bre = 0;
int release = 0;
key = ftok("/home/feng/fengfeng/",1);
shmid = shmget(key,2048,IPC_CREAT|0600);
if(shmid < 0)
{
perror("shmget");
exit(-1);
}
addr = shmat(shmid,NULL,0);
if(addr < 0)
{
perror("shmat");
exit(-1);
}
strcpy(addr,"hello world");
bre = shmdt(addr);
if(bre < 0)
{
perror("shmdt");
exit(-1);
}
release = shmctl(shmid,IPC_RMID,NULL);
if(release < 0)
{
perror("shmctl");
exit(-1);
}
return 0;
}
从共享内存读数据:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int shmid = 0;
char *p = NULL;
key_t key = 0;
int ret = 0;
char buf[1024] = {0};
key = ftok("/home/hua/huahua/",1);
shmid = shmget(key,1024,IPC_CREAT|0600);
if(shmid < 0)
{
perror("shmget");
exit(-1);
}
p = shmat(shmid,NULL,0);
if(p < 0)
{
perror("shmat");
exit(-1);
}
strcpy(buf,p);
printf("buf is %s\n",buf);
ret = shmdt(p);
if(ret < 0)
{
perror("shmdt");
exit(-1);
}
return 0;
}
更多推荐
所有评论(0)