共享内存示例

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;
}

子进程不继承父进程创建的共享内存,大家都是共享的。子进程继承父进程映射的地址。

猜你喜欢

转载自blog.csdn.net/baidu_33879812/article/details/82558010
今日推荐