共享内存的创建和映射shmget()和shmat()

原创 2012年07月21日 00:52:10

共享内存的实现分为两步:

1、创建共享内存,用到的函数是shmget();

2、映射共享内存,就是把这段创建的共享内存映射到具体的进程空间去,使用的函数是:shmat();

这样就可以使用不带缓冲的I/O读写命令对其进行操作了。

实例如下:

/*
 * shmem.c
 *
 *  Created on: 2012-7-20
 *      Author: liwei.cai
 */
/**
 * 该实例说明:如何使用基本的共享内存函数。
 * 功能:首先创建一个共享内存区,之后创建子进程,在父子进程中将共享内存
 * 分别映射到各自的进程地址空间中。
 * 	父进程先等待用户输入,然后将用户输入的字符串写入到共享内存,之
 * 后往共享内存的头部写入“WROTE”字符串表示父进程已成功写入数据。子进程
 * 一直等待共享内存的头部字符串是“WROTE”,然后将共享内存的有效数据打印
 * 出来,之后父子进程分别解除与共享内存的映射。
 * 	最后在子进程中删除共享内存。
 */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 2048

int main()
{
	pid_t pid;
	int shmid;
	char *shm_addr;
	char flag[] = "WROTE";
	char *buff;

	//创建共享内存
	if ((shmid = shmget(IPC_PRIVATE, BUFFER_SIZE, 0666)) < 0)
	{
		perror("shmget");
		exit(1);
	}
	else
	{
		printf("Create shared-memory: %d\n", shmid);
	}

	//显示共享内存的情况
	system("ipcs -m");

	pid = fork();
	if (pid == -1)
	{
		perror("fork");
		exit(1);
	}
	else if (pid == 0) //子进程
	{
		// 映射共享内存
		if ((shm_addr = shmat(shmid, 0, 0)) == (void*)-1)
		{
			perror("Child: shmat");
			exit(1);
		}
		else
		{
			printf("Child:Attach shared-memory: %p\n", shm_addr);
		}
		system("ipcs -m");

		//通过检查在共享内存的头部是否标志字符串“WROTE”来确认
		//父进程已经此案够共享内存写入有效数据
		while(strncmp(shm_addr, flag, strlen(flag)))
		{
			printf("Child: wait for enable data...\n");
			sleep(5);
		}
		//获取共享内存的有效数据并显示
		strcpy(buff, shm_addr + strlen(flag));
		printf("Child: Shared-memory: %s\n", buff);

		//解除共享内存映射
		if((shmdt(shm_addr)) < 0)
		{
			perror("shmdt");
			exit(1);
		}
		else
		{
			printf("Child: Deattach shared-memory\n");
		}
		system("ipcs -m");

		//删除共享内存
		if(shmctl(shmid, IPC_RMID, NULL) == -1)
		{
			perror("Child: shmctl(IPC_RMID)\n");
			exit(1);
		}
		else
		{
			printf("Delete shared-memory\n");
		}
		system("ipcs -m");
	}
	else	//父进程
	{
		//映射共享内存
		if ((shm_addr = shmat(shmid, 0, 0)) == (void*)-1)
		{
			perror("Parent: shmat");
			exit(1);
		}
		else
		{
			printf("Parent:Attach shared-memory: %p\n", shm_addr);
		}
		sleep(1);
		printf("\n Input some string: \n");
		fgets(buff, BUFFER_SIZE,stdin);
		strncpy(shm_addr + strlen(flag), buff, strlen(buff));
		strncpy(shm_addr, flag, strlen(flag));

		//解除共享内存映射
		if((shmdt(shm_addr)) < 0)
		{
			perror("shmdt");
			exit(1);
		}
		else
		{
			printf("Parent: Deattach shared-memory\n");
		}
		system("ipcs -m");

		waitpid(pid, NULL, 0);
		printf("Finished\n");
	}
	exit(0);
}

运行调试的时候出现,堆栈错误,请读者仔细阅读和修改代码,找出错误,附在下面。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Linux进程间通信——使用共享内存

下面将讲解进程间通信的另一种方式,使用共享内存。 一、什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的...

Linux进程间通信源码剖析,共享内存(shmget函数详解)

转至:http://blog.csdn.net/lanmanck/article/details/6092995 shmget int shmget(key_t key, size_t siz...

确保对象的唯一性——单例模式 (四):更好的单例实现方法(静态内部类)

3.5 一种更好的单例实现方法饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存;懒汉式单例类线程安全控制烦琐,而且性能受影响。可见,无论是饿汉式单例还是懒汉式单例都存在这样那样的问题,有没有一...

共享内存函数(shmget、shmat、shmdt、shmctl)及其范例

共享内存函数由shmget、shmat、shmdt、shmctl四个函数组成。下面的表格列出了这四个函数的函数原型及其具体说明。1.   shmget函数原型shmget(得到一个共享内存标识符或创建...

VI 行处理技巧数枚

最近在公司需要处理一些脚本,才感觉自己的vi太次了,在这里搞个备份,以备查阅: 1. 如何只保留匹配内容行而删除其他行? :v/pattern/d :help :v 2...

shmget - 共享内存

一. 共享内存介绍 系统V共享内存指的是把所有共享数据放在共享内存区域(IPC shared memory region),任何想要访问该数据的 进程都必须在本进程的地址空间新增一块内存区...

ROS使用笔记本自带USB摄像头运行pi_face_tracker,进行人脸识别

人脸识别在机器人应用当中算是一个热门的应用,在网上找了一些Haar算法的例子,在opencv下面跑都能正常识别,打算在ros中也跑一跑,在网上找了一下,找到了pi_face_tracker这个例子,它...

ROS实战之人脸检测

ROS实战之人脸检测ROS:indigo 摄像头:罗技c270 本次实战中人脸检测代码主要参考opencv源码中的facedetect.cpp,根据自己的需要进行裁剪。 编程思想: 在上一篇博...

ros_kinect人脸识别face_recognition

1.下载 $ cd ~/catkin_ws/src $ git clone https://github.com/procrob/procrob_functional.git --branch c...

IPC--共享内存 Share Memory 实例(shmget shmat shmdt shmctl)

/* * writeShareM.c * * Created on: 2011-11-20 * Author: snape */ #include #include #in...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)