首页 > 系统相关 >内存映射

内存映射

时间:2023-04-29 15:34:30浏览次数:29  
标签:addr 映射 int 内存 进程 include

 

/*
    内存映射:
        是将磁盘文件数据映射到内存,用户通过修改内存就能修改磁盘文件


        #include <sys/mman.h>

        void *mmap(void *addr, size_t length, int prot, int flags,
                    int fd, off_t offset);

            功能:将一个文件或设备的数据映射到内存中
            参数:
                addr:NULL,由内核决定
                length:要映射的数据的长度,值不能为0,建议使用文件的长度
                        获取文件的长度:stat lseek
                prot:对申请的内存映射区的操作权限
                    PROT_EXEC  Pages may be executed.

                    PROT_READ  Pages may be read.

                    PROT_WRITE Pages may be written.

                    PROT_NONE  Pages may not be accessed.
                    要操作映射内存,必须要有读权限,通过|连接权限
                flags:
                    MAP_SHARED:映射区的数据会自动和磁盘文件进行同步,进程间通信必须要设置这个选项
                    MAP_PRIVATE:不同步,写时复制
                fd:
                    需要映射文件的文件描述符
                    通过open得到
                    注意:文件大小不能为0,open权限不能于prot参数有冲突,open >= prot
                offset:
                    偏移量,一般不用,必须指定的是4k的整数倍,0表示不偏移
            返回值:
                成功:返回创建的内存首地址
                失败:返回MAP_FAILED,(void *) -1

        int munmap(void *addr, size_t length);
            功能:释放内存映射
            参数:
                addr:要释放的内存的首地址
                length:要释放的内存大小,要和mmap函数中的length值相同

*/

/*
    使用内存映射实现进程间通信:
    1、有关系的进程(父子进程)
        还没有子进程的时候
            通过唯一的父进程,先创建内存映射区
        有了内存映射区以后,创建子进程
        父子进程共享创建的内存映射区
    2、没有关系的进程间通信
        准备一个大小不是0的磁盘文件
        进程1 通过磁盘文件创建内存映射区
              得到一个操作这块内存的指针
        进程2 通过磁盘文件创建内存映射区
              得到一个操作这块内存的指针
        使用内存映射区通信
    注意:内存映射区通信,是非堵塞的



*/

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

int main()
{
    int fd = open("test.txt", O_RDWR | O_CREAT, 0777);
    int size = lseek(fd, 0, SEEK_END);
    //               默认   文件大小   与打开文件的权限相同 同步或非同步 默认 默认
    void *shared_addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(shared_addr == MAP_FAILED)
    {
        perror("mmap error");
        exit(-1);
    }



    int fork_flag = fork();
    if(fork_flag == 0)
    {
        strcpy((char *)shared_addr, "Hello World");
    }
    else
    {
        sleep(1);
        char str[1024] = {0};
        strcpy(str, (char *)shared_addr);
        printf("recve a info: %s\n", str);
    }

    munmap(shared_addr, size);
    close(fd);

    return 0;

}

 

标签:addr,映射,int,内存,进程,include
From: https://www.cnblogs.com/WTSRUVF/p/17364041.html

相关文章

  • 驱动开发:通过MDL映射实现多次通信
    在前几篇文章中LyShark通过多种方式实现了驱动程序与应用层之间的通信,这其中就包括了通过运用SystemBuf缓冲区通信,运用ReadFile读写通信,运用PIPE管道通信,以及运用ASYNC反向通信,这些通信方式在应对一收一发模式的时候效率极高,但往往我们需要实现一次性吐出多种数据,例如ARK工具中当我......
  • 驱动开发:通过MDL映射实现多次通信
    在前几篇文章中LyShark通过多种方式实现了驱动程序与应用层之间的通信,这其中就包括了通过运用SystemBuf缓冲区通信,运用ReadFile读写通信,运用PIPE管道通信,以及运用ASYNC反向通信,这些通信方式在应对一收一发模式的时候效率极高,但往往我们需要实现一次性吐出多种数据,例如ARK工具中当......
  • C内存分配
    堆上内存分配1.brk()和sbrk()progambreakprogrambreak记录了堆顶的地址,当使用brk或者sbrk系统调用时,programbreak的位置会随之改变brk()#include<unistd.h>intbrk(void*end_data_segment);brk(void*end_data_segment)将programbreak抬升到end_data_segment处,成......
  • 使用Addressable更好的管理内存
    你好,我是郑洪智,你可以叫我大智。我正在带小新学Unity。洪流学堂公众号回复addr,可以下载Addressable中文手册,更有视频教程哦~小新:“智哥,Assetbundle我只是大概学了一下,但是没咋用过。你说不用它就会有内存问题?”大智:“咱们来一起做个测试吧。对于工程里的资源,一般有三种方式加载实例......
  • 【GPU基础问题】GPU内存占用率很高利用率很低
    前言 问题描述查看nvidia-smi,发现显存占比很高,但是GPU-Util(GPU利用率)很低,在3%、7%、11%等几个参数之间反复跳动。watch-n0.5nvidia-smi也就是显卡并没有完全利用起来,导致训练很慢。原因分析GPU内存占用率(memoryusage) GPU内存利用率(volatileGPU-Util)  ......
  • java方法的内存及练习
    方法的内存一、方法调用的基本内存原理:Java内存分配栈:方法运行时使用的内存方法进栈运行,运行完毕就出栈堆:newl出来的,都在堆内存中开辟了一个小空间方法区:存储可以运行的class文件本地方法栈:JVM在使用操作系统功能的时候使用和我们开发无关寄存器:给CPU使用和......
  • 10 如何表示虚拟内存
    x86CPU的虚拟地址空间划分:一个应用往往拥有很大的连续地址空间,并且每个应用都是一样的,只有在运行时才能分配到真正的物理内存,在操作系统中被称为虚拟内存;x86CPU支持虚拟地址时要么开启保护模式要么开启长模式;保护模式下是32位,没有进行任何划分;长模式下64位,但是CPU只是实现了4......
  • Linux 内存管理 pt.1
    哈喽大家好,我是咸鱼 今天我们来学习一下Linux操作系统核心之一:内存 跟CPU一样,内存也是操作系统最核心的功能之一,内存主要用来存储系统和程序的指令、数据、缓存等 关于内存的学习,我会尽量以通俗易懂的方式且分成多篇文章去讲解 那么今天在pt.1文章中,我们来学习......
  • windows下按键映射
     includeiostreamincludewindows.husingnamespacestd;HHOOKhHook=0;LRESULTCALLBACKLowLevelKeyboardProc(intnCode,WPARAMwParam,LPARAMlParam){if(nCode==HC_ACTION){KBDLLHOOKSTRUCT*p=(KBDLLHOOKSTRUCT*)lParam;......
  • Jenkins java程序占用内存大 优化
       Linux系统下使用top命令,再输入M按钮,按照内存排序每个进程,发现jenkins占据内存过大,如下:   解决方式输入命令vim/etc/sysconfig/jenkins编辑jenkins文件,修改JENKINS_JAVA_OPTIONS属性:原来的属性如下: JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"  ......