一、共享内存概念:
共享内存是进程间通信中最简单的方法之一。共享内存允许两个或更多的进程访问同一块内存当一个进程改变了这块地址空间中内容,其他进程就会察觉到这个改变。
二、共享内存的特点:
1、共享内存允许两个不相关的进程访问同一个内存。
2、共享内存是两个正在运行的进程之间共享和传递数据的最有效的方法。
3、不同进程之间共享的内存通常安排同一段物理内存。
4、共享内存不存在任何互斥和同步机制,一般用信号量对临界资源进行保护。
5、接口简单
6、若一个进程正在访问共享内存中的写数据,在它做这一步之前,别的进程不应当去读写这块数据。
三、共享内存中的函数:
同一文件为#include<sys/ipc.h>
#include<sys/shm.h>
1、创建共享内存:
int shmget(key_t key,size_t size,int shmfalg)
功能:创建或打开一块共享内存区域。
参数: key:进程间通信的键值。
size:该共享存储段的长度。
shmflg:标识函数的行为及和共享内存的权限,其值如下:
IPC_CREAT:如果不存在就创建。
IPC_EXCl :如果已经存在就返回失败。
位或权限位:共享内存位或权限位可以设置共内存的访问权限,格式和open函数的mode_t一样。
成功返回共享内存标识符,失败返回-1
2、共享内存的映射:
void *shmat(shmid,const void *shmaddr,int shmflg);
功能:
将一个共享内存段映射到调用进程的数据段中,让进程和共享内存建立一种联系,让进程某个指针指向此共享内存。
参数:
shmid:共享内存标识符,shmget()的返回值。
shmaddr:共享内存映射地址,若为NULL则由系统自动指定。
shmflg:共享内存访问权限和映射条件(通常为0)。
0:共享内存具有可读可写权限。
SHM_PDONLY:只读。
SHM_RND:shmaddr 非空时才有效。
成功返回共享内存映射地址(相当于这个指针指向此共享内存),失败返回-1.
3、解除共享内存映射:
int shmdt(const void *shmaddr);
功能:
将共享内存和当前进程分离(仅仅是断开联系并不是删除共享内存,相当于让之前的指向此共享内存的指针,不再指向)。
参数:
shmaddr:共享内存映射地址。
成功返回0,失败返回-1。
4、共享内存的控制:
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
功能:
共享内存属性的控制。
参数:
shmgid:共享内存的标识符。
cmd:函数功能的控制,其值如下
IPC_RMID:删除(常用)。
IPC_SET:设置shmid_ds参数,相当于把共享内存原来的属性替换为buf里的属性值。
IPC_STAT:保存shmid_ds参数,把共享内存原来的属性备份到buf里。
SHM_LOCK:锁定共享内存段。
SHM_UNLOCK:解锁共享内存段。
buf:shmid_ds数据类型的地址用来存放和修改共享内存的属性(通常为NULL)
成功返回0,失败返回-1.
四、例子:
创建两个进程,在A进程中创建一个共享内存,并向其写入数据通过B进程从共享内存中读取数据。
shm_server.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#define BUFSZ 512
int main(int argc,char *argv[])
{
int shmid,ret;
char *shmadd;
shmid = shmget((key_t)1234,BUFSZ,IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
exit(EXIT_FAILURE);
}
shmadd = shmat(shmid,NULL,0);
if (shmadd < 0)
{
perror("shmat");
exit(EXIT_FAILURE);
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#define BUFSZ 512
int main(int argc,char *argv[])
{
int shmid,ret;
char *shmadd;
shmid = shmget((key_t)1234,BUFSZ,IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
exit(EXIT_FAILURE);
}
shmadd = shmat(shmid,NULL,0);
if (shmadd < 0)
{
perror("shmat");
exit(EXIT_FAILURE);
}
printf("copy data to shared-memory\n");
bzero(shmadd,BUFSZ);
strcpy(shmadd,"how are you,1h");
return 0;
}
printf("copy data to shared-memory\n");
bzero(shmadd,BUFSZ);
strcpy(shmadd,"how are you,1h");
return 0;
}
shm_clent.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#define BUFSZ 512
int main(int argc,char *argv[])
{
int shmid,ret;
char *shmadd;
shmid = shmget((key_t)1234,BUFSZ,IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
exit(EXIT_FAILURE);
}
shmadd = shmat(shmid,NULL,0);
if (shmadd < 0)
{
perror("shmat");
exit(EXIT_FAILURE);
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#define BUFSZ 512
int main(int argc,char *argv[])
{
int shmid,ret;
char *shmadd;
shmid = shmget((key_t)1234,BUFSZ,IPC_CREAT | 0666);
if (shmid == -1)
{
perror("shmget");
exit(EXIT_FAILURE);
}
shmadd = shmat(shmid,NULL,0);
if (shmadd < 0)
{
perror("shmat");
exit(EXIT_FAILURE);
}
printf("data = [%s]\n",shmadd);
ret = shmdt(shmadd);
if (ret == -1)
{
perror("shmdt");
exit(EXIT_FAILURE);
}
else
{
printf("deleted shared-memory\n");
}
shmctl(shmid,IPC_RMID,NULL);
return 0;
}
printf("data = [%s]\n",shmadd);
ret = shmdt(shmadd);
if (ret == -1)
{
perror("shmdt");
exit(EXIT_FAILURE);
}
else
{
printf("deleted shared-memory\n");
}
shmctl(shmid,IPC_RMID,NULL);
return 0;
}