共享内存实现分为两个步骤:
一、创建共享内存,使用shmget函数。
二、映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用shmat函数
由于这种方式是直接对用户空间的内存进行映射,故效率较高,使用起来也方便;
但需要注意的是,多个进程并发访问共享内存时的同步控制问题,可用信号量操作解决。
系统调用:shmget( ) ;
原型:int shmget ( key_t key, int size, int shmflg );
返回值:如果成功,返回共享内存段标识符。
如果失败,则返回- 1:
errno = EINVAL (无效的内存段大小)
EEXIST (内存段已经存在,无法创建)
EIDRM (内存段已经被删除)
ENOENT (内存段不存在)
EACCES (权限不够)
ENOMEM (没有足够的内存来创建内存段)
函数中的key_t如何获得已经在上一篇文章中说明了
系统调用:shmat();
原型:int shmat ( int shmid, char *shmaddr, int shmflg);
返回值:如果成功,则返回共享内存段连接到进程中的地址。
如果失败,则返回- 1:
errno = EINVAL (无效的IPC ID 值或者无效的地址)
ENOMEM (没有足够的内存)
EACCES (存取权限不够)
当一个进程不在需要共享的内存段时,它将会把内存段从其地址空间中脱离。
系统调用:shmdt();
调用原型:int shmdt ( char *shmaddr );
返回值:如果失败,则返回- 1:
errno = EINVAL (无效的连接地址)
举例:shm1.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
int main()
{
key_t ipckey;
int shmid;
int i;
char *addr_c;
char srcbuf[8]="abcdefg";
ipckey=ftok("/home/yds/tmp/shmipc",0);
shmid=shmget(ipckey,1024,IPC_CREAT|0666);
if(shmid==-1)
{
printf("creat shm error!\n");
return -1;
}
addr_c=(char *)shmat(shmid,0,0);
if((int)addr_c==-1)
{
printf("attach shm error!\n");
return -1;
}
while(1)
{
for(i=0;i<strlen(srcbuf);i++)
{
srcbuf[i]=srcbuf[i]+1;
}
strcpy(addr_c,srcbuf);
sleep(1);
}
shmdt(addr_c);
return 0;
}
shm2.c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
int main()
{
key_t ipckey;
int shmid;
int i;
char *addr_c;
ipckey=ftok("/home/yds/tmp/shmipc",0);
shmid=shmget(ipckey,1024,IPC_CREAT|0666);
if(shmid==-1)
{
printf("creat shm error!\n");
return -1;
}
addr_c=(char *)shmat(shmid,0,0);
if((int)addr_c==-1)
{
printf("attach shm error!\n");
return -1;
}
while(1)
{
sleep(2);
printf("string(shm) is:%s\n",addr_c);
}
shmdt(addr_c);
return 0;
}
以上两个程序shm1.c先运行,shm2.c后运行 由于没有采用信号量机制对进程进行同步,所以只能先人为规定一下执行顺序了,只在说明问题,不在实用。
进程shm1负责每秒钟向共享内存中写入数据, shm2负责每两秒从共享内存中读数据,这个例子中key_t ipckey 保证操作的共享内存是同一个。上一篇文章有关于key_t的解释