Linux下共享内存有mmap和System V两种方式
1.mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。由此看来mmap并不纯粹是为实现共享内存而设计的
2.System V 共享内存是通过映射特殊文件系统 shm 中的文件实现进程间的共享内存通信,即把所有共享数据放在共享内存区域, 任何想要访问该数据的进程都必须在本进程的地址空间新增一块内存区域,用来映射存放共享数据的物理内存页面。
两者从应用上来看,区别不大,一个是操作普通文件,一个是操作交换分区上的 shm 文件系统
1. mmap方式
写进程:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <sys/mman.h> #include <string.h> #include <errno.h> #include <unistd.h> #define SHMNAME "shm_ram" #define OPEN_FLAG O_RDWR|O_CREAT #define OPEN_MODE 00777 #define FILE_SIZE 4096*4 int main(int argc,char **argv) { int ret = -1; int fd = -1; void* add_w = NULL; //创建或者打开一个共享内存 fd = shm_open(SHMNAME, OPEN_FLAG, OPEN_MODE); if(-1 == (ret = fd)) { perror("shm failed: "); return ret;; } //调整确定文件共享内存的空间 ret = ftruncate(fd, FILE_SIZE); if(-1 == ret) { perror("ftruncate"); return ret;; } // 映射目标文件的存储区 add_w = mmap(NULL, FILE_SIZE, PROT_WRITE, MAP_SHARED, fd, SEEK_SET); if(NULL == add_w) { perror("mmap"); return ret;; } // memcpy 内存共享 写入内容 memcpy(add_w, "howaylee", sizeof("howaylee")); // 取消映射 ret = munmap(add_w, FILE_SIZE); if(-1 == ret) { perror("munmap add_w faile: "); return ret;; } // 删除内存共享 /*shm_unlink(SHMNAME); if(-1 == ret) { perror("shm_unlink faile: "); return ret;; }*/ }
读进程
int main(int argc,char **argv) { int ret = -1; int fd = -1; char buf[4096] = {0}; void* add_r = NULL; //创建或者打开一个共享内存 fd = shm_open(SHMNAME, OPEN_FLAG, OPEN_MODE); if(-1 == (ret = fd)) { perror("shm"); return ret; } //调整确定文件共享内存的空间 ret = ftruncate(fd, FILE_SIZE); // 16k if(-1 == ret) { perror("ftruncate"); return ret; } // 映射目标文件的存储区 add_r = mmap(NULL, FILE_SIZE, PROT_READ, MAP_SHARED, fd, SEEK_SET); if(NULL == add_r) { perror("mmap"); return ret; } // memcpy 内存共享 写入内容 memcpy(buf, add_r, sizeof(buf)); printf("buf = %s\n", buf); // 取消映射 ret = munmap(add_r, FILE_SIZE); if(-1 == ret) { perror("munmap"); return ret; } }
2. System V方式
system V API比较简洁,只涉及到 shmget(),shmmat(),shmmdt(),shmctrl()四个函数,与信号量函数命名一致
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MY_SHM_ID 0x00004589 #define IPC_BUF_SIZE 1*1024*1024 pthread_mutex_t mutex; bool WriteShmMsg(const char *szMsg) { if(pthread_mutex_init(&mutex,NULL)!=0) { printf("错误:初始化锁失败\n"); return false; } // 创建共享内存区 if((shmid=shmget(MY_SHM_ID,IPC_BUF_SIZE,0600|IPC_CREAT))<0) { perror("shmget"); return false; } void *mem; // 映射共享内存区 if((mem=shmat(shmid,0,0))==(void*)-1) { perror("shmat"); return false; } sprintf((char*)mem,"%s",szMsg); // 写入消息 shmdt(mem); // 取消共享内存映射 pthread_mutex_unlock(&mutex); return true; }
更多内容参见:
http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html
http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index2.html
相关推荐
在使用共享内存的程序异常退出时,由于没有释放掉共享内存,在调试时会出现错误。您可以使用shell命令来查看与释放已经分配的共享内存,下面将详细说明如何进行查看和释放分配的共享内存的方法。
linux 共享内存简单使用
完整的Linux共享内存实例,包括读进程、写进程、信号量
linux下面的共享内存详解,详细介绍了共享内存的使用和药注意的事项
linux共享内存源码例子 linux共享内存源码例子
自己整理的Linux5个共享内存头文件, 通过编写共享内存实验,进一步了解使用共享内存的具体步骤,同时加深对共享内存的理解。在本实验中,采用信号量作为同步机制完善两个进程(“生产者”和“消费者”)之间的通信。
linux的信息传输方式之一,共享内存,希望对初学者有用
Linux共享内存C语言编程示例(包含一个应用的范例)
Linux系统提供了多种IPC机制,如信号、管道、信号量、消息队列、共享内存和套接字等,其中以共享 内存效率最高.
要使用共享内存,应该有如下步骤: 1.开辟一块共享内存 shmget() 2.允许本进程使用共某块共享内存 shmat() 3.写入/读出 4.禁止本进程使用这块共享内存 shmdt() 5.删除这块共享内存 shmctl()或者命令行下ipcrm ftok...
讲解了下linux共享内存函数
头哥实践平台操作系统实训四 Linux 共享内存2
linux共享内存专题编程笔记
linux 共享内存的完整代码。 /* 共享内存 是一种常用的进程间通信机制。 1、创建内存共享区 2、映射内存共享区 3、进程间通信 4、撤销映射 5、删除内存共享区(一定要手动删除,不然会一直存在,哪怕程序结束...
Linux 下C++共享内存、信号量封装,实现进程同步
Linux采用共享内存与消息队列,进程间通信,完成视频推流功能
运行程序,可在linux下创建指定共享内存名,指定大小的共享内存,用于检测此名称此大小的共享内存在linux系统下是否能创建成功
基于C语言和linux共享内存的数据分发软件