概述:
System V共享区在概念上类似于POSIX共享内存区。代之以调用shm_open后调用mmap的是,先调用shmget,再调用shmat。
相关函数:
shmdt函数:
int shmget(key_t key, size_t size, int shmflg); 返回:若成功返回为共享内存区对象,若出错返回-1。
key既可以是ftok的返回值,也可以是IPC_PRIVATE。
size以字节为单位指定内存的区的大小。当实际操作为创建一个新的共享内存区时,必须指定一个不为0的size的值。如果实际操作为访问一个已经存在的共享内存区,那么size为0。
oflag表示权限组合。
typedef struct stu
{
char name[32];
int age;
}STU;
int main(int argc,char *argv[])
{
int shmid;
shmid = shmget(1234,sizeof(STU),IPC_CREAT | 0666);
if(shmid == -1)
ERR_EXIT("shmget");
shmat函数:
void *shmat(int shmid, const void *shmaddr, int shmflg);返回:若成功则为映射区的起始地址,若出错则返回-1.
其中shmid是由shemget返回的标识符。shmat的返回值是所指定的共享内存区在调用进程内的起始地址。确定这个地址的规则如下:
如果shmaddr是一个空指针,那么系统替调用者选择地址。
如果shmaddr是一个非空指针,那么返回地址取决于调用者是否给flag参数指定了SHM_RND。
如果没有指定SHM_RND,那么相应的共享内存区附接到有shmaddr参数指定的地址;
如果指定了SHM_RND,那么相应的共享内存区附接到有shmaddr参数指定的地址向下舍入SHMLBA常值。
flag表示权限组合。
STU *p;
p = shmat(shmid,NULL,0);
if(p == (void*)-1)
ERR_EXIT("shmat");
shmdt函数:
int shmdt(const void *shmaddr);返回:若成功返回0,若出错返回-1
当一个进程完成某个共享内存区的使用时,它可调用shmdt断接这个内存区。
shmdt(p);
shmctl函数:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmctl提供了对一个内存区的多种操作。该函数提供了三个命令:
IPC_RMID:从系统中删除由shmid标识的共享内存区并拆除它。
IPC_SET: 给所指定的共享内存区设置其shmid_ds结构的以下三个成员:shm_perm.uid、shm_perm.gid和shm_perm.mode 。
IPC_STAT:(通过buff参数)向调用者返回所指定共享内粗去当前的shmid_ds结构。
注:参考UNIX网络编程卷二:进程间同信
完整验证代码:
读:
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0); \
typedef struct stu
{
char name[32];
int age;
}STU;
int main(int argc,char *argv[])
{
int shmid;
shmid = shmget(1234, 0, 0);
if(shmid == -1)
ERR_EXIT("shmget");
STU *p;
p = shmat(shmid,NULL,0);
if(p == (void*)-1)
ERR_EXIT("shmat");
printf("name = %s\nage=%d\n",p->name,p->age);
memcpy(p,"quit",4);
shmdt(p);
return 0;
}
写:
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while(0); \
typedef struct stu
{
char name[32];
int age;
}STU;
int main(int argc,char *argv[])
{
int shmid;
shmid = shmget(1234,sizeof(STU),IPC_CREAT | 0666);
if(shmid == -1)
ERR_EXIT("shmget");
STU *p;
p = shmat(shmid,NULL,0);
if(p == (void*)-1)
ERR_EXIT("shmat");
strcpy(p->name,"lisi");
p->age = 20;
while(1)
{
if(memcmp(p,"quit",4) == 0)
break;
}
shmdt(p);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}