共享内存是允许多个进程共享一块内存,由此来达到交换信息的进程通信机制;它很快没有中间介质,唯一的不足就是需要一定的同步机制控制多个进程对同一块内存的读/写,,它的原理如下:
每个共享内存段都有一个shmind_ds结构,定义如下:
struct shmid_ds
{
struct ipc_perm shm_perm;
int shm_segsz;
ushort shm_lkcnt ;
pid_t shm_cpid;
pid_t shm_lpid;
ulong shm_nattach;
time_t shm_atime;
time_t shm_dtime;
time_t shm_ctime;
};
上面的这个结构不是很懂,而shmid_ds结构每个域的含义也很复杂,这里不多介绍,下面来介绍一下有关共享内存的函数调用.
一,共享内存的创建与打开
要使用共享内存,首先要创建一个共享内存区域,创建共享内存的函数如下:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include (key_t key,int size,int flag);//参数key表示所创建或打开的共享内存的关键字;
//参数size表示共享内存区域的大小只在创建一个新的共享内存时生效;
//参数flag表示调用函数的操作类型.
函数shmget除了可以创建一个新的共享内存外,也可用于打开一个已存在的共享内存;
下面举个例子说明:
用shmget函数编制一个创建或打开一块新的共享内存的函数,代码如下:
1 #include <sys/type.h> 2 #include <sys/ipc.h> 3 #include <sys/shm.h> 4 5 int openshm(int size) 6 { 7 int shmid; 8 if(shmid=shmget(IPC_PRIVATE,size,0)==-1) 9 { 10 printf("'Get shared memory failed!\n); 11 return -1; 12 } 13 return shmid; 14 }
二,共享内存的操作
当一个共享内存创建或打开后,某个进程如果想使用该共享内存则必须将此内存区域附加到它的地址空间,附加操作的相关调用如下:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
void *shmat(int shmid,void *addr,int flag);//参数shmid表示要附加的共享内存段的引用标识符;
//参数flag用于表示shmat函数的操作方式。
当一个进程对共享区域的访问完成以后,可以调用shmat函数使共享内存区域与该进程的地址空间分离,shmdt函数的说明如下:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int shmdt(void *addr);
次函数仅用于将共享内存区域与进程的地址空间分离,不会删除共享内存本身,参数addr为要分离的共享内存区域的指针,是调用函数shmat的返回值,成功则返回值为0,否则为-1.
3,共享内存的控制
对共享内存区域的具体控制操作是通过函数shmctl来实现的,shmctl函数的说明如下:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
void shmctl(int shmid,int cmd,shmid_ds *buf);//参数shmid为共享内存段的引用标识符;
//参数cmd用于表示调用该函数希望执行的操作;
//参数buf是指向shmid_ds结构的指针。
下面来举个例子说明共享内存的实现,
共享内存实现分为两个步骤:
一、创建共享内存,使用shmget函数。
二、映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用shmat函数。
代码如下:
1 #include <sys/types.h>
2 #include <sys/ipc.h>
3 #include <sys/shm.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #define BUFSZ 2048
8 int main()
9 {
10 int shmid;
11 char *shmadd;
12
13 if((shmid=shmget(IPC_PRIVATE,BUFSZ,0666))<0)
14 {
15 perror("shmget");
16 exit(1);
17 }
18 else
19 printf("created shared-memory: %d\n",shmid);
20 system("ipcs -m");
21
22 if((shmadd=shmat(shmid,0,0))<(char *)0){
23 perror("shmat");
24 exit(1);
25 }
26 else
27 printf("attached shared-memory\n");
28 system("ipcs -m");
29
30 if((shmdt(shmadd))<0){
31 perror("shmdt");
32 exit(1);
33 }
34 else
35 printf("deleted shared-memory\n");
36 system("ipcs -m");
37
38 exit(0);
39 }