文档章节

父子进程通过mmap进行通信

kuerant
 kuerant
发布于 2014/06/18 17:10
字数 466
阅读 271
收藏 6
点赞 0
评论 0

本来打算使用pipe进行父子进程之间的数据交互(应用场景是父进程向多个子进程分发数据,子进程进行处理);但是担心pipe的性能,转而使用mmap实现。

废话少叙,上代码。

#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>

#define SHMFILE "shm.data"

typedef struct cell_t {
    int state;
    #define CELL_READY  1
    #define CELL_CLEAR  0
    int size;
    char    data[64];
} cell_t;

int main(void) {
    signal( SIGCHLD, SIG_IGN );
    
    int i, ret = 0;
    int fd = open(SHMFILE, O_CREAT | O_RDWR | O_TRUNC, 0600);
    if ( fd < 0 ) {
        fprintf(stderr, "fail to open %s -- %s\n", SHMFILE, strerror(errno));
        return  2;
    }
    int n_cells = 8;
    int shm_size = sizeof(cell_t) * n_cells;
    off_t off = lseek(fd, shm_size, SEEK_END);
    if ( off != (off_t)shm_size ) {
        fprintf(stderr, "fail to seek %s (got:%ld want:%d) -- %s\n", SHMFILE, off, shm_size, strerror(errno));
        return  3;
    }
    ret = write(fd, "", 1);
    if ( ret < 0 ) {
        fprintf(stderr, "fail to write %s -- %s\n", SHMFILE, strerror(errno));
        return  5;
    }

    cell_t* cell = (cell_t *) mmap(NULL, shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if ( cell == NULL ) {
        fprintf(stderr, "fail to mmap %s -- %s\n", SHMFILE, strerror(errno));
        return  7;
    }
    for (i=0; i<n_cells; i++) {
        memset( cell + i, 0, sizeof(cell_t) );
    }
    int id = 3;
    int pid = fork();
    if (pid < 0) {
        fprintf(stderr, "fail to fork child -- %s\n", strerror(errno));
        return  1;
    }
    else if (pid == 0) {
        // child process
        pid = getpid();
        fprintf(stdout, "\tC#%d I am here ...\n", pid);
        
        cell_t* c = &cell[id];
        
        for ( i=0; i<5; i++ ) {
            if ( c->state == CELL_READY ) {
                fprintf(stdout, "\tC#%d size=%d data='%s'\n", pid, c->size, c->data);
                c->state = CELL_CLEAR;
                break;
            }
            sleep(1);
        }
        fprintf(stdout, "\tC#%d byebye\n", pid);

        munmap(cell, shm_size);
        close(fd);
        exit(0);
    }

    pid = getpid();
    fprintf(stdout, "P#%d I am here ...\n", pid);
    sleep(1);
    {
        cell_t* c = &cell[id];
        char*   data = "Hello,World.";
        c->size = strlen(data);
        memmove( c->data, data, c->size );
        c->state = CELL_READY;
        fprintf(stdout, "P#%d cell->state=%d\n", pid, c->state);
        sleep(5);
        fprintf(stdout, "P#%d cell->state=%d\n", pid, c->state);
    }
    fprintf(stdout, "P#%d byebye\n", pid);

    munmap(cell, shm_size);
    close(fd);
    return  0;
}

© 著作权归作者所有

共有 人打赏支持
kuerant
粉丝 9
博文 54
码字总数 12892
作品 0
通州
Linux进程间通信—— 内存映射

Linux环境进程间通信(五): 共享内存(上) 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地...

li_wen01 ⋅ 2017/07/29 ⋅ 0

Linux内存管理之mmap详解

一. mmap系统调用 1. mmap系统调用 mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。munmap执行相反...

zhangyujsj ⋅ 2016/03/12 ⋅ 0

Linux进程间通信源码剖析,共享内存(mmap)

来自:http://blog.csdn.net/dancing999/archive/2008/01/13/2042473.aspx 范例1:两个进程通过映射普通文件实现共享内存通信 范例1包含两个子程序:mapnormalfile1.c及mapnormalfile2.c。编...

长平狐 ⋅ 2012/06/12 ⋅ 0

[转]mmap详解

共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式, 因为进程可以直接读写内存,而不需要任何 数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据...

Orion ⋅ 2011/09/16 ⋅ 0

linux内存管理——mmap函数详解

mmap函数是unix/linux下的系统调用。 当存在客户-服务程序中复制文件时候,其数据流如下,要经历四次数据复制,开销很大。 如果采用共享内存的方式,那么将大大优化IO操作,数据流变成了如下...

闪亮的蛤蟆 ⋅ 04/20 ⋅ 0

Bryce1010的操作系统课程设计

1.作业调度 2.磁盘调度 常见的磁盘调度算法大致分为以下5类: FCFS、SSTF、SCAN、CSCAN、FSCAN 程序实现了上述5类调度算法。 其中,当前磁道和要求服务的磁道均由系统随机产生。 程序入口是m...

Fire_to_cheat_ ⋅ 2017/12/23 ⋅ 0

Linux进程间通信-------共享内存之mmap详解

mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。 头文件...

B_ice ⋅ 2016/07/31 ⋅ 0

基于visual c++之windows核心编程代码分析(17)通过pipe进程间通信

管道是一种用于在进程间共享数据的机制,其实质是一段共享内存。Windows系统为这段共享的内存设计采用数据流I/0的方式来访问。由一个进程读、另一个进程写,类似于一个管道两端,因此这种进程...

junwong ⋅ 2012/03/09 ⋅ 0

Linux-进程间通信(一、匿名管道与命名管道)

LINUX进程间通信(二、消息队列) 匿名管道: 用法: 单个进程中的管道几乎没有任何用处,通常,调用pipe的进程接着调用fork,从而创建了一个父进程与子进程之间的半双工的IPC通道。在当前进...

sssssuuuuu666 ⋅ 2017/12/20 ⋅ 0

第15章 进程间通行 15.6 XSI IPC 15.7 消息队列

15.6 XSI IPC (1)3种称作XSI IPC的IPC是: 1)消息队列 2)信号量 3)共享存储器 (2)标识符和键 1)标识符:是一个非负整数,用于引用IPC结构。是IPC对象的内部名。 2)键:IPC对象的外部...

fxdhdu ⋅ 2015/10/23 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

骰子游戏代码开源地址

因为阿里云现在服务器已经停用了,所以上面的配置已经失效。 服务端开源地址:https://gitee.com/goalya/chat4.git 客户端开源地址:https://gitee.com/goalya/client4.git 具体运行界面请参考...

算法之名 ⋅ 41分钟前 ⋅ 0

设计模式--装饰者模式

装饰者模式 定义 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。 通用类图 意图 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比...

gaob2001 ⋅ 今天 ⋅ 0

JavaScript零基础入门——(八)JavaScript的数组

JavaScript零基础入门——(八)JavaScript的数组 欢迎大家回到我们的JavaScript零基础入门,上一节课我们讲了有关JavaScript正则表达式的相关知识点,便于大家更好的对字符串进行处理。这一...

JandenMa ⋅ 今天 ⋅ 0

sbt网络问题解决方案

转自:http://dblab.xmu.edu.cn/blog/maven-network-problem/ cd ~/.sbt/launchers/0.13.9unzip -q ./sbt-launch.jar 修改 vi sbt/sbt.boot.properties 增加一个oschina库地址: [reposit......

狐狸老侠 ⋅ 今天 ⋅ 0

大数据,必须掌握的10项顶级安全技术

我们看到越来越多的数据泄漏事故、勒索软件和其他类型的网络攻击,这使得安全成为一个热门话题。 去年,企业IT面临的威胁仍然处于非常高的水平,每天都会看到媒体报道大量数据泄漏事故和攻击...

p柯西 ⋅ 今天 ⋅ 0

Linux下安装配置Hadoop2.7.6

前提 安装jdk 下载 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz 解压 配置 vim /etc/profile # 配置java环境变量 export JAVA_HOME=/opt/jdk1......

晨猫 ⋅ 今天 ⋅ 0

crontab工具介绍

crontab crontab 是一个用于设置周期性被执行的任务工具。 周期性执行的任务列表称为Cron Table crontab(选项)(参数) -e:编辑该用户的计时器设置; -l:列出该用户的计时器设置; -r:删除该...

Linux学习笔记 ⋅ 今天 ⋅ 0

深入Java多线程——Java内存模型深入(2)

5. final域的内存语义 5.1 final域的重排序规则 1.对于final域,编译器和处理器要遵守两个重排序规则: (1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用...

江左煤郎 ⋅ 今天 ⋅ 0

面试-正向代理和反向代理

面试-正向代理和反向代理 Nginx 是一个高性能的反向代理服务器,但同时也支持正向代理方式的配置。

秋日芒草 ⋅ 今天 ⋅ 0

Spring 依赖注入(DI)

1、Setter方法注入: 通过设置方法注入依赖。这种方法既简单又常用。 类中定义set()方法: public class HelloWorldOutput{ HelloWorld helloWorld; public void setHelloWorld...

霍淇滨 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部