共享内存区是可用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. js的style和getArribute("属性名")

    getAttribute()是HTML DOM的一个方法,用以获取HTML元素的属性(如id,name,type以及其他自定义属性). style是HTML DOM的一个关于样式的对象,style对象 ...

  2. CSS的导入方式:link与import方式的区别

    在前端开发中,加载CSS样式文件有两种方式:link方式与import方式,它们之间的区别主要有以下几点: 1.兼容性不一样 link是一个HTML标签,所以它不存在兼容性问题,而import方式则具 ...

  3. 分享一个js加密的几种方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. spring boot 热启动

    spring boot热启动有两种方式 1. 以Maven插件的形式去加载,所以启动时使用通过Maven命令mvn spring-boot:run启动,而通过Application.run方式启动的会 ...

  5. 【CS Round #39 (Div. 2 only) C】Reconstruct Sum

    [Link]:https://csacademy.com/contest/round-39/task/reconstruct-sum/ [Description] 给你一个数字S; 让你找有多少对A, ...

  6. XML学习总结(1)——XML入门

    一.XML语法学习 学习XML语法的目的就是编写XML 一个XML文件分为如下几部分内容: 文档声明 元素 属性 注释 CDATA区 .特殊字符 处理指令(processing instruction ...

  7. IntelliJ IDEA如何导入maven结构的web工程

    第一步:打开一个现有(也可以不打开,直接用import选择Maven类型)的IntelliJ IDEA工程,点击菜单的"File"->"new"-> ...

  8. HDU 1043 八数码(A*搜索)

    在学习八数码A*搜索问题的时候须要知道下面几个点: Hash:利用康托展开进行hash 康托展开主要就是依据一个序列求这个序列是第几大的序列. A*搜索:这里的启示函数就用两点之间的曼哈顿距离进行计算 ...

  9. c#操作ElasticSearch5详解

    c#操作ElasticSearch详解 ElasticSearch系列学习 ElasticSearch第一步-环境配置 ElasticSearch第二步-CRUD之Sense ElasticSearc ...

  10. Vue框架学习笔记

    <div id="app"> </div> var app = new Vue({ el:"#app", // 绑定的元素 data:{ ...