共享内存区是可用IPC形式中最快的。一旦内存区映射到共享它的进程的地址空间,进程间数据的传递就不再涉及内核。然而往该共享内存区存放信息或从中取走信息的进程间通常须要某种形式的同步。不再涉及内核是指:进程不再通过运行不论什么进入内核的系统调用来彼此传递数据。内核必须建立同意各个进程共享该内存区的内存映射关系。然后一直管理内存区。

默认情况下通过fork派生的子进程并不与其父进程共享内存区。

mmap函数把一个文件或一个Posix共享内存区对象映射到调用进程的地址空间。使用该函数的目的有:

1、使用普通文件以提供内存映射I/O。

2、使用特殊文件以提供匿名内存映射。

3、使用shm_open以提供无亲缘关系进程间的Posix共享内存区。

#include <sys/mman.h>
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);

addr指定描写叙述符fd应被映射到的进程内空间的起始地址。

若为空指针,则由内核自己去选择起始地址。不管哪种情况。该函数的返回值都是描写叙述符fd所映射到内存区的起始地址。

len是映射到调用进程地址空间中的字节数,它从被映射文件开头起第offset个字节处開始算。

offset通常设置为0。

prot參数指定内存区映射区的保护。

有下面四种:PROT_READ(数据可读)、PROT_WRITE(数据可写)、PROT_EXEC(数据可运行)、PROT_NONE(数据不可訪问)。

flags有下面三种:MAP_SHARED(变动是共享的)、MAP_PRIVATE(变动是私有的)、MAP_FIXED(准确地解释addr參数)。

父子进程之间共享内存区的方法之中的一个是,父进程在调用fork前先指定MAP_SHARED调用mmap。

mmap成功返回后,fd參数能够关闭。该操作对由mmap建立的映射关系没有影响。

为某个进程的地址空间删除一个映射关系,我们调用munmap。

(int munmap(void *addr, size_t len))

调用msync来运行同步。

(int msync(void *addr, size_t len, int flags))

注意:不是全部文件都能进程内存映射,比如:试图把一个訪问终端或套接字的描写叙述符映射到内存将导致mmap返回一个错误。这些类型的描写叙述符必须使用read和write来訪问。

mmap的还有一个用途是在无亲缘关系的进程间提供共享的内存区。

程序实例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h> #define SEM_NAME "mysem"
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) int
main(int argc, char **argv)
{
int fd, i, nloop, zero = 0;
int *ptr;
sem_t *mutex; if(argc != 3){
printf("usage:incrl <pathname> <#nloops>\n");
return -1;
}
nloop = atoi(argv[2]); /*open file , initialize to 0, map into memory*/
fd = open(argv[1], O_RDWR | O_CREAT, FILE_MODE);
write(fd, &zero, sizeof(int));
ptr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd); /*create, initialize, and unlink semaphore*/
mutex = sem_open(SEM_NAME, O_CREAT | O_EXCL, FILE_MODE, 1);
if(mutex < 0){
printf("sem_open error.\n");
return -1;
}
sem_unlink(SEM_NAME); setbuf(stdout, NULL); /*stdout is unbuffered*/
if(fork() == 0){
for(i = 0; i < nloop; i++){
sem_wait(mutex);
printf("child:%d\n", (*ptr)++);
sem_post(mutex);
}
exit(0);
} /*parent*/
for(i = 0; i < nloop; i++){
sem_wait(mutex);
printf("parent:%d\n", (*ptr)++);
sem_post(mutex);
}
exit(0);
}

注意:内存映射一个普通文件时,内存中映射区的大小通常等于该文件的大小。然而文件大小和内存映射区大小能够不同。

Linux环境编程之共享内存区(一):共享内存区简单介绍的更多相关文章

  1. Linux环境编程相关的文章

    Linux环境编程相关的文章 好几年没有接触Linux环境下编程了,好多东西都有点生疏了.趁着现在有空打算把相关的一些技能重拾一下,顺手写一些相关的文章加深印象. 因为不是写书,也受到许多外部因素限制 ...

  2. 【转】Linux环境搭建FTP服务器与Python实现FTP客户端的交互介绍

    Linux环境搭建FTP服务器与Python实现FTP客户端的交互介绍 FTP 是File Transfer Protocol(文件传输协议)的英文简称,它基于传输层协议TCP建立,用于Interne ...

  3. (转)Linux环境进程间通信系列(五):共享内存

    原文地址:http://www.cppblog.com/mydriverc/articles/29741.html 共享内存可以说是最有用的进程间通信方式,也是最快的 IPC 形式.两个不同进程 A ...

  4. Linux环境编程导引

    计算机系统硬件组成 总线 贯穿整个系统的一组电子管道称为总线, 分为: 片内总线 系统总线 数据总线DB 地址总线AB 控制总线CB 外部总线 I/O设备 I/O设备是系统与外界联系的通道 键盘鼠标是 ...

  5. Linux环境编程之同步(四):Posix信号量

    信号量是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语.有三种类型:Posix有名信号量,使用Posix IPC名字标识.Posix基于内存的信号量,存放在共享内存区中:System ...

  6. Linux 环境编程:dirfd参数 有关解析

    背景 在Unix环境编程中,系统提供了很多以at结尾的函数,如openat.fstatat等,而这类函数通常有一个特点,就是形参列表中多了int dirfd 例如: int open(const ch ...

  7. Linux环境编程--waitpid与fork与execlp

    waitpid waitpid(等待子进程中断或结束) 表头文件 #include<sys/types.h> #include<sys/wait.h> 定义函数 pid_t w ...

  8. Linux环境编程进程间通信机制理解

    一.Linux系统调用主要函数 二.创建进程 1.创建子进程系统调用fork() 2.验证fork()创建子进程效果 3.系统调用fork()与挂起系统调用wait() 三.模拟进程管道通信 四.pi ...

  9. 笔记整理:计算CPU使用率 ----linux 环境编程 从应用到内核

    linux 提供time命令统计进程在用户态和内核态消耗的CPU时间: [root@localhost ~]# time sleep real 0m2.001s user 0m0.001s sys 0 ...

随机推荐

  1. Ubuntu 12.04使用演示

    今年年初,发布了Ubuntu 12.04(代号Precise Pangolin),但正式版预计将于2012年的4月底发布,作者对最新版本的ubuntu做了试用,先将操作视频与大家分享.更多内容请关注本 ...

  2. android 移植ffmpeg后so库的使用

    今天折腾了一天,可算是有所收获,成功的用jni调用了libffmpeg中的一个方法-----avcodec_version(),至于avcodec_version()是干什么用的我不大清楚,应该是获取 ...

  3. Android java.lang.NoSuchFieldError: No static field xxx of type I in class Lcom/XX/R$id; or its superclasses

    项目开发快到尾声,突然发现之前一个模块莫名其妙的奔溃了,我的内心也是奔溃的.以前一直都是好好的,也没去动过它,为啥会出现这样的问题呢? 下面我会根据自己的理解来看待问题 android是怎么根据id查 ...

  4. Ubuntu+PyQt5+Python3.6+Qt Designer 实现可视化窗口的编辑

    一.为什么写这片博文 近期将实验室的电脑的OS换成了ubuntu,想对linux进一步的了解和使用.在使用的过程中想用python+pyqt5写一个音乐播放器和视频播放器(这也是linux的乐趣所在) ...

  5. Linux-PS1变量详解

    1.PS1 要修改linux终端命令行颜色,我们需要用到PS1,PS1是Linux终端用户的一个环境变量,用来说明命令行提示符的设置.在终端输入命令:#set,即可在输出中找到关于PS1的定义如下: ...

  6. ORA-01653 无法在表空间扩展的解决办法 -- 增加表空间大小或给表空间增加数据文件

    转自原文 ORA-01653 无法在表空间扩展的解决办法 -- 增加表空间大小或给表空间增加数据文件 当前系统的数据量越来越大的,昨天还运行正常的数据库,突然无法使用了.经过定位发现是"OR ...

  7. UVa 11094 - Continents

    题目:有一些岛屿在湖中.地图用两种字符表示.当前处在位置是一个岛屿.求除了当前岛屿外的最大岛屿. 分析:图论,floodfill.直接利用dfs求联通部分的面积就可以,然后取出最大. 说明:横线没有边 ...

  8. IO流学习笔记

    1.File类 文件和目录路径名的抽象表示形式. 4种构造方法 File(File parent, String child) File(File parent, String child) File ...

  9. alert警告框

    标签中写: <div class="alert alert-warning fade in"> <button class="close" d ...

  10. 福建省第八届 Triangles

    Problem Description This is a simple problem. Given two triangles A and B, you should determine they ...