Linux编程练习 --SystemV共享内存

1.共享内存段的基本概念

共享内存就是由几个进程共享一段内存区域,可以说是IPC最快形式,因为它无须任何中间操作,它只是把内存段直接映射到调用进程的地址空间中。共享内存段通信的使用方式和消息通信是类似的。首先用shmget系统调用为进程创建一个共享内存段,当需要该共享内存时,利用系统调用shmat将申请的共享内存段映射到进程的私有空间中,之后进程可以用与访问其他虚拟地址空间相同的方法对它进行访问了。多个进程对同一个共享内存访问是互斥的,但互斥控制要与共享内存相关联的所有进程自己去完成。所以共享内存经常和信号量使用。

 

2.共享内存的系统操作

A.创建一段共享内存系统调用语法:
#include <sys/shm.h>
int shmget(key_t key,int size,int flags);
key 共享内存的键值,可以为IPC_PRIVATE,也可以用整数指定一个
size 共享内存字节长度
flags 共享内存权限位。
shmget 调用成功后,如果key 用新整数指定,且flags 中设置了IPC_CREAT
位,则返回一个新建立的共享内存段标识符。如果指定的key 已存在则返回与key
关联的标识符。不成功返回-1

 


B.令一段共享内存附加到调用进程中的系统调用语法:
#include <sys/shm.h>
char *shmat(int shmid, char *shmaddr,int flags)
shmid 由 shmget 创建的共享内存的标识符
shmaddr 总为0,表示用调用者指定的指针指向共享段
flags 共享内存权限位
shmat 调用成功后返回附加的共享内存首地址


C.令一段共享内存从到调用进程中分离出去的系统调用语法:
#include <sys/shm.h>
int shmdt(char *shmadr);
shmadr 进程中指向附加共享内存的指针
shmdt 调用成功将递减附加计数,当计数为0,将删除共享内存。调用不成功
返回-1。

 

 

下面进行练习,创建一个共享内存段,然后两次调用shmat将它映射到进程数据空间的不同位置(起始地址由内核决定),接着通过连入地址shmadd1对共享内存实施写操作,通过另一个连入地址shmadd2从该共享读取数据并输出:

/*share_memory.c*/ #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <stdio.h> #include <stdlib.h> #define BUFSZ 2048 int main() { int shmid,i; int *ptr; int key; char *shmadd1,*shmadd2; /*创建共享内存*/ key = ftok(".",1); if((shmid=shmget(key,BUFSZ,0666))<0) { perror("shmget"); exit(1); } else printf("created shared-memory: %d/n",shmid); system("ipcs -m"); /*把共享内存段映射到进程的数据空间中, 这里第二个参数为0表示由内核选择地址 成功时返回该共享内存段的数据空间首地址*/ if((shmadd1=shmat(shmid,0,0))<(char *)0) { perror("shmat1"); exit(1); } else printf("attached shared-memory/n"); if((shmadd2=shmat(shmid,0,0))<(char *)0) { perror("shmat1"); exit(1); } else printf("attached shared-memory/n"); system("ipcs -m"); /*从地址1处将数据写入共享内存*/ ptr = (int*)shmadd1; for(i=0;i<6;i++) { *ptr++ = i; } /*从地址2将数据从共享内存段读出*/ ptr = (int *)shmadd2; for(i=0;i<6;i++) { printf("value: %d/n",*ptr++); } /*删除共享内存*/ if((shmdt(shmadd1))<0){ perror("shmdt"); exit(1); } else printf("deleted shared-memory/n"); if((shmdt(shmadd2))<0){ perror("shmdt"); exit(1); } else printf("deleted shared-memory/n"); system("ipcs -m"); exit(0); }

编译,运行

你可能感兴趣的:(Linux编程练习 --SystemV共享内存)