a.共享内存区域是被多个进程共享的一部分物理内存。
b.多个进程都可把该共享内存映射到自己的虚拟内存空间。所有用户空间的进程若要操作共享内存,都要将其映射到自己的虚拟空间中,通过映射的虚拟空间地址去操作共享内存,从而达到进程间的数据通信。
c.共享内存是进程间共享数据的一种最快的方法,一个进程向共享内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。
d.本身不提供同步机制,可通过信号量进行同步。
e.提升数据处理效率,一种效率最高的IPC机制。
将用到的通知管道封装,头文件:
/*************************************************************************
> File Name: tell.h
> Author: CC
> Mail: [email protected]
> Created Time: 2018年09月09日 星期日 13时43分42秒
************************************************************************/
#ifndef __TELL_H__
#define __TELL_H__
//管道初始化
extern void init();
//利用管道进行等待
extern void wait_pipe();
//利用管道进行通知
extern void notify_pipe();
//销毁管道
extern void destroy_pipe();
#endif
管道封装实现:
/*************************************************************************
> File Name: tell.h
> Author: CC
> Mail: [email protected]
> Created Time: 2018年09月09日 星期日 13时43分42秒
************************************************************************/
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include"tell.h"
#include<unistd.h>
static int fd[2];
//管道初始化
void init()
{
if(pipe(fd) < 0){
perror("pipe error!\n");
exit(1);
}
}
//利用管道进行等待
void wait_pipe()
{
char c;
//管道读写默认是阻塞的
if(read(fd[0],&c,1) < 0){
perror("wait pipe error!\n");
exit(1);
}
}
//利用管道进行通知
void notify_pipe()
{
char c = 'c';
if(write(fd[1],&c,1) != 1){
perror("write error!\n");
exit(1);
}
}
//销毁管道
void destroy_pipe()
{
close(fd[0]);
close(fd[1]);
}
共享内存主函数实现:
/*************************************************************************
> File Name: cal_shm.c
> Author: CC
> Mail: [email protected]
> Created Time: 2018年09月09日 星期日 13时51分12秒
************************************************************************/
#include<unistd.h>
#include<stdio.h>
#include<sys/shm.h>
#include<stdlib.h>
#include<string.h>
#include"tell.h"
#include<sys/wait.h>
int main(void)
{
//创建共享内存
int shmid;
if((shmid = shmget(IPC_PRIVATE,1024,IPC_CREAT|IPC_EXCL|0777)) < 0){
perror("shmget error!\n");
exit(1);
}
pid_t pid;
init();//初始化管道
if((pid = fork()) < 0){
perror("fork error");
exit(1);
}else if(pid > 0){
//parent
//虚拟内存映射
int *pi = (int *)shmat(shmid,0,0);
if(pi == (int *)-1){
perror("shmat error!\n");
exit(1);
}
*pi = 100;
*(pi+1) = 200;
//操作完毕,解除映射。
shmdt(pi);
notify_pipe();
destroy_pipe();
wait(0);
}else{
//child
//子进程阻塞,等待父进程先往共享内存写入数据
wait_pipe();
//子紧凑去共享内存读取数据,也要进行映射
int *pi = (int*)shmat(shmid,0,0);
if(pi == (int*)-1){
perror("shmat error");
exit(1);
}
printf("start:%d,end:%d",*pi,*(pi+1));
//解除映射
shmdt(pi);
//删除共享内存
shmctl(shmid,IPC_RMID,NULL);
destroy_pipe();
}
return 0;
}
子进程不继承父进程创建的共享内存,大家都是共享的。子进程继承父进程映射的地址。