mmap msync munmap close

mmap函数创建匿名映射区 mmap函数创建匿名映射区 mmap一般创建思路 1,打开一个文件,得到该文件的文件描述符 int fd = open(char *path,int mode) 2, 创建该文件的内存映射区 void *mptr = mmap(void *addr,size_t len,int prot,int mode,ssize_t fd,size_t offset); addr ------- NUL... 阅读详情


https://blog.youkuaiyun.com/ctthuangcheng/article/details/8674191

 

       open 打开文件后——>使用mmap建设文件映射;建立文件映射后,可以对映射到的空间进行操作。用msync同步到文件中。
        问:close后对映射空间的操作能够同步到文件中吗?
        答:可以,只要文件映射存在,就可以向你映射空间的内容写入文件,实现空间和文件的同步。
实例代码::
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <string.h>   
  4. #include <unistd.h>   
  5. #include <sys/mman.h>   
  6. #include <sys/types.h>   
  7. #include <fcntl.h>   
  8. int main(int argc, char *argv[])  
  9. {  
  10.  int fd;  
  11.  char *addr;  
  12.  char *str = "Hello World";  
  13.  fd = open("./a",O_CREAT|O_RDWR|O_TRUNC,0666);  
  14.  if(fd == -1)  
  15.  {  
  16.   perror("open file fail:");  
  17.   exit(1);  
  18.  }  
  19.  if(ftruncate(fd,4096)==-1)  
  20.  {  
  21.   perror("ftruncate fail:");  
  22.   close(fd);  
  23.   exit(1);  
  24.  }  
  25.  addr =(char *) mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);  
  26.  if(addr == (char *)MAP_FAILED)  
  27.  {  
  28.   perror("mmap fail:");  
  29.   exit(1);  
  30.  }  
  31.  memset(addr,' ',4096);  
  32.    
  33.  memcpy(addr,str,strlen(str));                       //hello world  1   
  34.  close(fd);  
  35.  memcpy(addr+strlen(str),str,strlen(str));           //hello world  2   
  36.  if(msync(addr,4096,MS_SYNC)==-1)  
  37.  {  
  38.   perror("msync fail:");  
  39.   exit(1);  
  40.  }  
  41.       munmap(addr,4096);  
  42.  return 0;  
  43. }  
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <unistd.h>  
  5. #include <sys/mman.h>  
  6. #include <sys/types.h>  
  7. #include <fcntl.h>  
  8. int main(int argc, char *argv[])  
  9. {  
  10.  int fd;  
  11.  char *addr;  
  12.  char *str = "Hello World";  
  13.  fd = open("./a",O_CREAT|O_RDWR|O_TRUNC,0666);  
  14.  if(fd == -1)  
  15.  {  
  16.   perror("open file fail:");  
  17.   exit(1);  
  18.  }  
  19.  if(ftruncate(fd,4096)==-1)  
  20.  {  
  21.   perror("ftruncate fail:");  
  22.   close(fd);  
  23.   exit(1);  
  24.  }  
  25.  addr =(char *) mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);  
  26.  if(addr == (char *)MAP_FAILED)  
  27.  {  
  28.   perror("mmap fail:");  
  29.   exit(1);  
  30.  }  
  31.  memset(addr,' ',4096);  
  32.    
  33.  memcpy(addr,str,strlen(str));                       //hello world  1  
  34.  close(fd);  
  35.  memcpy(addr+strlen(str),str,strlen(str));           //hello world  2  
  36.  if(msync(addr,4096,MS_SYNC)==-1)  
  37.  {  
  38.   perror("msync fail:");  
  39.   exit(1);  
  40.  }  
  41.       munmap(addr,4096);  
  42.  return 0;  
  43. }  
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
 int fd;
 char *addr;
 char *str = "Hello World";
 fd = open("./a",O_CREAT|O_RDWR|O_TRUNC,0666);
 if(fd == -1)
 {
  perror("open file fail:");
  exit(1);
 }
 if(ftruncate(fd,4096)==-1)
 {
  perror("ftruncate fail:");
  close(fd);
  exit(1);
 }
 addr =(char *) mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
 if(addr == (char *)MAP_FAILED)
 {
  perror("mmap fail:");
  exit(1);
 }
 memset(addr,' ',4096);
 
 memcpy(addr,str,strlen(str));                       //hello world  1
 close(fd);
 memcpy(addr+strlen(str),str,strlen(str));           //hello world  2
 if(msync(addr,4096,MS_SYNC)==-1)
 {
  perror("msync fail:");
  exit(1);
 }
      munmap(addr,4096);
 return 0;
}
========================================

  //下面的代码把文件1.ls中的内容通过mmap函数写入2.ls中,忽略出错处理

  int fd=open("1.ls",O_RDONLY);

  int fd2=open("2.ls",O_CREAT|O_RDWR|O_TRUNC,S_IRUSR|S_IWUSR);//必须设置读写权限,若只有写权限,会产生SIGSEGV信号

  //mmap进行文件映射时必须先读取文件`

  struct stat st;

  fstat(fd,&st);

  lseek(fd2,st.st_size-1,SEEK_SET);

  write(fd2,"",1);        //必须的,如果不设置,当写入数据的时候会遇到文件结束符,产生SIGBUS信号

  void *_src=mmap(NULL,st.st_size,PROT_READ,MAP_SHARED, fd,0);

  void *_des=mmap(NULL,st.st_size,PROT_WRITE,MAP_SHARED,fd2,0);

  close(fd);      //关闭文件后 依然可修改文件内容

  close(fd2);

  memcpy(_des,_src,st.st_size);

  总结一下,可能产生的问题如下:

  1.进行文件映射的描述符必须拥有读权限,否则会产生SIGSEGV信号

  2.把内存内容写入映射文件时,必须确保被写文件当前位置到文件结尾的长度不小于所写内容长度,否则产生SIGBUS信号

  3.关闭文件描述符并不能保证文件内容不被修改

  4.munmap并不能使映射的内容写回磁盘

=======================================================================================

在编写设备驱动程序的时候,如果要想把设备内存映射到用户空间,那需要我们实现mmap,通过看ldd3上面的介绍,对实现mmap有了一点了解. 
书上介绍主要是利用 
int remap_pfn_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long pfn, unsigned long size, pgprot_t prot) 函数或者 
int io_remap_page_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long phys_addr, unsigned long size, pgprot_t prot)函数来实现,它们负责建立新的页表.这两个函数的区别是第一个函数是在参数pfn指向实际系统RAM的时候使用,而第二个函数是在 phys_addr指向I/O内存的时候使用.对于ARM平台来说,系统内存和端口应该是统一编址的,所以两个函数是等价的. 
还有另外一个函数就是nopage函数,是VMA结构体中可以填充的一个函数,在虚拟页没有所对应的物理页的时候,会调用此函数,来分配一个物理页给虚拟页. 
  int remap_page_range(unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot) 

其中from是映射开始的虚拟地址。这个函数为虚拟地址空间from和from+size之间的范围构造页表; 
phys_addr是虚拟地址应该映射到的物理地址; 
size是被映射区域的大小; 
prot是保护标志。 
remap_page_range的处理过程是对from到form+size之间的每一个页面,查找它所在的页目录和页表(必要时建立页表),清除页表项旧的内容,重新填写它的物理地址与保护域。 
remap_page_range可以对多个连续的物理页面进行处理。<<Linux设备驱动程序>>指出, 
remap_page_range只能给予对保留的页和物理内存之上的物理地址的访问,当对非保留的页使用 
remap_page_range时,缺省的nopage处理控制映射被访问的虚地址处的零页。所以在分配内存后,就要对所分配的内存置保留位,它是通过函数mem_map_reserve实现的,它就是对相应物理页面置 
PG_reserved标志位。

remap_pfn_range 通过你的页帧号来建立页表, 并映射到用户空间!
一般情况是你的驱动分配一块内存,然后在驱动的mmap中使用这块内存的 物理地址转成页帧号, 再调用remap_pfn_range!
1,假设你是通过kmalloc(),get_free_pages()等分配的,这种内存页是不能通过remap_pfn_range()映射出去的,要对 每个页面调用SetPageReserverd()标记为“保留”才可以,virt_to_phys()函数只是得到其物理地 址,remap_pfn_range()中的第三个参数是要求物理页便的“帧”号,即pfn,所以你的phys还要“> > PAGE_SHIFT”操作 
2,假设你是通过vmalloc分配得来的,同上,不同的是要用vmalloc_to_pfn 
3,用kmalloc,get_free_pages,vmalloc分配的物理内存页面最好还是不要用remap_pfn_page方法,建议使用VMA的nopage方法 
4,对于这样的设备内存,最好对调用pgprot_nocached(vma-> vm_page_prot)后传给remap_pfn_range,防止处理器缓存 
==================================================================================
系统调用过程(详见: ARM linux系统调用的实现原理) :
void*  mmap(void *, size_t, int, int, int, off_t);       //bionic/libc/unistd/mmap.c     (head file: bionic/libc/include/sys/mman.h) 
  |

void*  __mmap2(void*, size_t, int, int, int, size_t);     // bionic/libc/arch-arm/syscalls/__mmap2.S   ( __NR_mmap2 = __NR_SYSCALL_BASE + 192 )

  |    ( arch/arm/kernel/calls.S )

sys_mmap2         // ( arch/arm/kernel/entry-common.S )

  |

sys_mmap_pgoff            //( mm/mmap.c )          SYSCALL_DEFINE6(mmap_pgoff, )

   |

do_mmap_pgoff(file, addr, len, prot, flags, pgoff);   //   mm/mmap.c

可能合并VMA
否则新分配一个VMA
然后
error = file->f_op->mmap(file, vma);
就调用了驱动里的mmap      
这时候vma->vm_pgoff = pgoff    (这个pgoff就是map(offset, len , fd ,...)  中的 offset ,当然经过处理了,PAGE_SHIFT移来移去的)
=============================================================
以下是Camera mmap的一个例子:
  1. <SPAN style="FONT-SIZE: 13px">/*! 
  2.  * V4L interface - mmap function 
  3.  * @param file        structure file * 
  4.  * @param vma         structure vm_area_struct * 
  5.  * @return status     0 Success, EINTR busy lock error, ENOBUFS remap_page error 
  6.  */  
  7. static int mxc_mmap(struct file *file, struct vm_area_struct *vma)  
  8. {  
  9. struct video_device *dev = video_devdata(file);  
  10. unsigned long size;  
  11.      int res = 0;  
  12.      cam_data *cam = video_get_drvdata(dev);  
  13.      pr_err("=============================camera mmap\n");  
  14.      pr_err("In MVC:mxc_mmap\n");  
  15.      pr_err("   pgoff=0x%lx, start=0x%lx, end=0x%lx\n",  
  16.             vma->vm_pgoff, vma->vm_start, vma->vm_end);  
  17.      /* make this _really_ smp-safe */  
  18.      if (down_interruptible(&cam->busy_lock))  
  19.                  return -EINTR;  
  20.      size = vma->vm_end - vma->vm_start;  
  21.      vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);  
  22.      if (remap_pfn_range(vma, vma->vm_start,  
  23.                      vma->vm_pgoff, size, vma->vm_page_prot)) {  
  24.            pr_err("ERROR: v4l2 capture: mxc_mmap: "  
  25.                         "remap_pfn_range failed\n");  
  26.            res = -ENOBUFS;  
  27.            goto mxc_mmap_exit;  
  28.      }  
  29.      vma->vm_flags &= ~VM_IO;/* using shared anonymous pages */  
  30.      mxc_mmap_exit:  
  31.      up(&cam->busy_lock);  
  32.      return res;  
  33. }</SPAN>  
  1. <span style="font-size: 13px;">/*! 
  2.  * V4L interface - mmap function 
  3.  * @param file        structure file * 
  4.  * @param vma         structure vm_area_struct * 
  5.  * @return status     0 Success, EINTR busy lock error, ENOBUFS remap_page error 
  6.  */  
  7. static int mxc_mmap(struct file *file, struct vm_area_struct *vma)  
  8. {  
  9. struct video_device *dev = video_devdata(file);  
  10. unsigned long size;  
  11.      int res = 0;  
  12.      cam_data *cam = video_get_drvdata(dev);  
  13.      pr_err("=============================camera mmap\n");  
  14.      pr_err("In MVC:mxc_mmap\n");  
  15.      pr_err("   pgoff=0x%lx, start=0x%lx, end=0x%lx\n",  
  16.             vma->vm_pgoff, vma->vm_start, vma->vm_end);  
  17.      /* make this _really_ smp-safe */  
  18.      if (down_interruptible(&cam->busy_lock))  
  19.                  return -EINTR;  
  20.      size = vma->vm_end - vma->vm_start;  
  21.      vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);  
  22.      if (remap_pfn_range(vma, vma->vm_start,  
  23.                      vma->vm_pgoff, size, vma->vm_page_prot)) {  
  24.            pr_err("ERROR: v4l2 capture: mxc_mmap: "  
  25.                         "remap_pfn_range failed\n");  
  26.            res = -ENOBUFS;  
  27.            goto mxc_mmap_exit;  
  28.      }  
  29.      vma->vm_flags &= ~VM_IO;/* using shared anonymous pages */  
  30.      mxc_mmap_exit:  
  31.      up(&cam->busy_lock);  
  32.      return res;  
  33. }</span>  
/*!
 * V4L interface - mmap function
 * @param file        structure file *
 * @param vma         structure vm_area_struct *
 * @return status     0 Success, EINTR busy lock error, ENOBUFS remap_page error
 */
static int mxc_mmap(struct file *file, struct vm_area_struct *vma)
{
struct video_device *dev = video_devdata(file);
unsigned long size;
     int res = 0;
     cam_data *cam = video_get_drvdata(dev);
     pr_err("=============================camera mmap\n");
     pr_err("In MVC:mxc_mmap\n");
     pr_err("   pgoff=0x%lx, start=0x%lx, end=0x%lx\n",
            vma->vm_pgoff, vma->vm_start, vma->vm_end);
     /* make this _really_ smp-safe */
     if (down_interruptible(&cam->busy_lock))
                 return -EINTR;
     size = vma->vm_end - vma->vm_start;
     vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
     if (remap_pfn_range(vma, vma->vm_start,
                     vma->vm_pgoff, size, vma->vm_page_prot)) {
           pr_err("ERROR: v4l2 capture: mxc_mmap: "
                        "remap_pfn_range failed\n");
           res = -ENOBUFS;
           goto mxc_mmap_exit;
     }
     vma->vm_flags &= ~VM_IO;/* using shared anonymous pages */
     mxc_mmap_exit:
     up(&cam->busy_lock);
     return res;
}
========================================
用户层调用:
mmap (NULL, mCaptureBuffers[i].length,PROT_READ | PROT_WRITE, MAP_SHARED, fd_v4l, mCaptureBuffers[i].phy_offset);
以下是抓取的Log:
 [   46.355719] =============================camera mmap
[   46.360704] In MVC:mxc_mmap
[   46.363635]    pgoff=0x93900, start=0x40c0f000, end=0x40cbf000
[   46.459041] =============================camera mmap
[   46.464109] In MVC:mxc_mmap
[   46.466908]    pgoff=0x93a00, start=0x40dbf000, end=0x40e6f000
[   46.569979] =============================camera mmap
[   46.575116] In MVC:mxc_mmap
[   46.577927]    pgoff=0x93b00, start=0x42692000, end=0x42742000
[   46.631274] =============================camera mmap
[   46.636332] In MVC:mxc_mmap
[   46.639130]    pgoff=0x93c00, start=0x42842000, end=0x428f2000
[   46.673606] =============================camera mmap
[   46.678661] In MVC:mxc_mmap
[   46.681459]    pgoff=0x93d00, start=0x429f2000, end=0x42aa2000
拍照:
[ 1072.567111] =============================camera mmap
[ 1072.572256] In MVC:mxc_mmap
[ 1072.575093]    pgoff=0x92c00, start=0x42692000, end=0x42952000
[ 1072.591292] =============================camera mmap
[ 1072.596321] In MVC:mxc_mmap
[ 1072.599119]    pgoff=0x91000, start=0x42952000, end=0x42c12000
[ 1072.612007] =============================camera mmap
[ 1072.616990] In MVC:mxc_mmap
[ 1072.619852]    pgoff=0x91400, start=0x42f25000, end=0x431e5000
返回preview:
[ 1074.351975] =============================camera mmap
[ 1074.357060] In MVC:mxc_mmap
[ 1074.359895]    pgoff=0x91700, start=0x40c0a000, end=0x40cba000
[ 1074.369823] =============================camera mmap
[ 1074.374837] In MVC:mxc_mmap
[ 1074.377635]    pgoff=0x93900, start=0x40cc5000, end=0x40d75000
[ 1074.385910] =============================camera mmap
[ 1074.390883] In MVC:mxc_mmap
[ 1074.393713]    pgoff=0x93e00, start=0x40d75000, end=0x40e25000
[ 1074.402028] =============================camera mmap
[ 1074.407004] In MVC:mxc_mmap
[ 1074.409808]    pgoff=0x92b00, start=0x40e25000, end=0x40ed5000
[ 1074.417813] =============================camera mmap
[ 1074.422813] In MVC:mxc_mmap
[ 1074.425610]    pgoff=0x91600, start=0x42692000, end=0x42742000
切换到录像:
[ 1148.276637] =============================camera mmap
[ 1148.281664] In MVC:mxc_mmap
[ 1148.284470]    pgoff=0x92b00, start=0x40e00000, end=0x40e98000
[ 1148.293967] =============================camera mmap
[ 1148.298943] In MVC:mxc_mmap
[ 1148.301780]    pgoff=0x93900, start=0x42323000, end=0x423bb000
[ 1148.311097] =============================camera mmap
[ 1148.316121] In MVC:mxc_mmap
[ 1148.318920]    pgoff=0x93e00, start=0x423bb000, end=0x42453000
[ 1148.328422] =============================camera mmap
[ 1148.333448] In MVC:mxc_mmap
[ 1148.336246]    pgoff=0x93c00, start=0x42453000, end=0x424eb000
[ 1148.346153] =============================camera mmap
[ 1148.351130] In MVC:mxc_mmap
[ 1148.353981]    pgoff=0x93d00, start=0x424eb000, end=0x42583000


==================================================================

深入解析mmap内存映射文件:原理、优势与高性能I/O实践 文件I/O是系统编程中的基础操作,传统read/write系统调用涉及用户空间与内核空间之间的数据拷贝和上下文切换,在频繁操作或大文件场景下可能成为性能瓶颈。内存映射文件(mmap)技术通过将文件直接映射到进程的虚拟地址空间,实现了用户程序对文件数据的直接内存访问,消除了不必要的数据拷贝,体现了零拷贝(Zero-Copy)的设计思想。其核心价值在于将文件I/O操作转化为内存访问,极大提升了大数据量随机访问、进程间通信等场景的效率。这一技术在高性能服务器、数据库引擎、游戏开发及中间件中广泛应用,尤其适合处理日 阅读详情

相关推荐

Linux内存映射技术mmap原理与应用实践

内存映射是操作系统提供的高效文件访问机制,通过建立虚拟内存与文件的直接映射,使应用程序可以像操作内存一样访问文件数据。其核心原理是利用页缓存减少数据拷贝,通过虚拟内存管理实现高效地址转换。该技术显著提升了大数据文件处理的性能,特别适用于数据库文件操作、日志分析等场景。结合共享内存特性,mmap还能实现高效的进程间通信。在实际工程中,需要注意映射粒度控制、同步机制设计等关键问题。通过合理使用大页内存、预读优化等技巧,可以进一步提升性能表现。

weixin_33946605的博客 431

Linux系统编程 | 进程间的通信

什么是进程间通信 Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷贝到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC, InterProcess Communication) 图解: 常用的进程间通信方式 1、管道(使用最简单) 2、信号(开销最小) 3、共享映射区(无血缘关系) 4、本地套接字

weixin_45615071的博客 295

深入解析mmap内存映射:原理、性能优化与C语言实战

内存映射(Memory-mapped I/O)是现代操作系统提供的一种高效文件访问机制,它通过将磁盘文件直接映射到进程的虚拟地址空间,实现了文件与内存的无缝对接。其核心原理基于操作系统的虚拟内存管理和页缓存机制,当进程访问映射区域时,通过缺页异常触发按需加载,数据从磁盘流入页缓存,同时建立虚拟地址到物理页的映射。这种技术价值在于实现了近乎内存的访问速度,同时保持了文件数据的实时性,特别适用于需要频繁随机访问大文件的场景,如数据库索引、搜索引擎和大型配置文件处理。通过mmap,开发者可以像操作内存一样读写文件

djph26741的博客 463

mmap和munmap对文件进行操作(读写等)

//mmap、munmap函数的使用 #include <stdio.h> #include <string.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <sys/mman.h...

luciusvorenus 767

C++高性能文件系统开发:内存映射I/O原理与虚拟内存交互深度解析

在操作系统和文件系统开发中,内存映射I/O(MMIO)是一种将文件或设备直接映射到进程虚拟地址空间的核心技术。其原理基于虚拟内存管理,通过建立虚拟内存区域(VMA)与文件地址空间的关联,实现按需分页(Demand Paging)机制。当程序首次访问映射区域时,会触发缺页中断(Page Fault),内核随后从页缓存(Page Cache)加载数据或分配物理页,这一过程由内存管理单元(MMU)协同完成。该技术的核心价值在于实现了近乎零拷贝的数据访问,显著减少了用户态与内核态之间的上下文切换和数据复制开销,从而

weixin_34117211的博客 433

【AutoDL + Langchain-Chatchat】从零构建高效本地 RAG 知识库问答系统:实战保姆级教程(含避坑指南)

本文详细阐述如何在AutoDL云平台,如何利用Langchain-Chatchat构建高效的本地RAG知识库问答系统,并深入解析RAG架构。从环境搭建到实战部署,从问题排查到性能优化,提供一份全面实用的指南,助力开发者快速构建智能问答应用。

拾光夕拾的博客 1803

认真分析mmap:是什么 为什么 怎么用

mmap基础概念 mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后,进程就可以采用指针的方式读写操作这一段内存,而系统会自动回写脏页面到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实...

weixin_30493401的博客 5237

光模块的封装工艺有哪些?

COB封装传统的单路10Gb/s或25Gb/s速率的光模块采用SFP封装将电芯片和TO封装的光收发组件焊接到PCB板上组成光模块。但对于40G及以上速率的高速光模块,受激光器速率限制(多为25G),主要通过多通道并行实现,如40G由4×10G实现,而100G则由4×25G实现。蝶形封装:壳体通常为长方体,结构及实现功能通常比较复杂,可以内置制冷器、热沉、陶瓷基块、芯片、热敏电阻、背光监控,并且可以支持所有以上部件的键合引线。BOX封装属于蝶形封装的一种,用于多通道并行封装。

WaytoICT- Explore ICT Technology, Build Your Tech Path 3806

文件映射mmap、msync、munmap(open后建立文件映射,close后文件映射依然存在,msync依然可以实现同步)

文件映射: open 打开文件后—>使用mmap建设文件映射;建立文件映射后,可以对映射到的内存空间进行读/写操作。 然后使用msync将修改结果同步到文件中。 问题: 问close后对映射空间的操作能够同步到文件中吗? 经过测试: 可以,只要文件映射存在,就可以通过msync将映射空间的内容写入文件,实现空间和文件的同步。 应用场景: 在实际的项目

u010154760的专栏 3044

别再死磕U-Net了!用PyTorch手把手教你搭建ResUnet,搞定医学图像分割(附完整代码)

本文详细介绍了如何利用PyTorch搭建ResUnet模型,通过引入残差连接解决医学图像分割中的梯度消失、特征退化和细节丢失问题。与传统U-Net相比,ResUnet在Dice系数和收敛速度上均有显著提升,特别适合处理脑部MRI等复杂医学图像。文章还提供了完整的代码实现和关键训练技巧,帮助开发者快速掌握这一先进技术。

weixin_42552637的博客 326

Petalinux 2021.1 + Vivado 2021 实战:手把手教你为Zynq板卡移植Linux并搞定AXI DMA驱动

本文详细介绍了基于Petalinux 2021.1和Vivado 2021工具链,为Zynq开发板移植Linux系统并开发AXI DMA驱动的全流程。从环境配置、硬件设计到驱动适配与性能优化,提供了实战避坑技巧和版本特异性问题的解决方案,帮助开发者快速构建高速数据传输系统。

weixin_42641741的博客 386

Linux初学之文件映射

Linux初学之文件映射 函数:open,mmap,munmap,msync,close 函数介绍:       Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上), 通过对这段内存的读取和修改, 实现对文件的读取和修改。 头文件: #include #include 原型: void *mmap(void *addr, size_t leng

咏月东南 1163

深度强化学习算法PPO训练Pendulum

returnadv = 0print('状态空间维度:', state_n)print('动作空间维度:', action_n)steps = []if done:breakif done:breakelse:steps = []if done:break。

weixin_43336108的博客 808

使用mmap即文件映射实现文件的快速复制

#include &lt;unistd.h&gt; #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;error.h&gt; #include &lt;sys/mman.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/stat.h&gt; #inc

云计算? 269

COMSOL介电弹性体数值仿真指南:预拉伸圆形DEA的稳态变形分析(I)

本期博客是《COMSOL介电弹性体数值仿真指南》系列博客中的一期。聚焦于介电弹性体驱动器(DEA)中最为经典的预拉伸圆形DEA驱动器构型,对其物理特性及数值仿真总体方案进行介绍与讨论。

忘了面孔的Batou 453

099、多摄融合与变焦系统:广角到长焦的无缝切换算法

本文分享了多摄融合与变焦系统开发中的实战经验和关键挑战。作者通过一个旗舰机项目案例,揭示了广角到长焦切换时画面抖动问题的根源——融合算法误将视差当作运动补偿,并提出"视差冻结窗口"的解决方案。文章总结了三大多摄融合难点:物理视差处理、亮度差异补偿和切换时机把控,详细阐述了分层架构设计、融合权重计算等核心技术。同时强调了产线校准的重要性,并给出五项实用建议:允许边缘鬼影保留、参数场景化配置、加强产线检测、完善调试接口,以及合理运用AI技术。全文展现了多摄融合技术在时间、空间和感知维度上的复杂平衡艺术。

sundong_81的博客 45

OK6410A 开发板 (八) 96 linux-5.11 OK6410A文件的访问 open-mmap-close

用户空间用的mmap函数,是glibc 提供的 声明通过 man mmap 查找 #include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); mmap 其中的一个用途(共享文件映射/私有文件映射) 是 访问文件 demo #include <sys/mman.h> #include <sys/stat.h> .

u011011827的博客 194

把 SAP Query 用到极致:ABAP Query 的核心概念、配置流程、权限与运输治理全解析

摘要:SAP Query 是一款面向业务用户的自助报表工具,可解决标准报表无法满足业务需求的问题。其核心由四大组件构成:Queries(报表定义)、InfoSets(数据视图)、User Groups(权限分组)和Translation(多语言支持)。通过SQ03、SQ02、SQ01事务码分步创建用户组、数据视图和查询,业务用户无需ABAP知识即可生成Basic List(明细)、Statistics(统计)和Ranked List(排名)三种报表形式。典型案例展示了如何为采购部门设计包含明细追溯和Top1

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 179

系统api-共享内存

共享内存

x13262608581的博客 275

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

mmap方法用于存档

mmap方法用于存档 有时候一个游戏,像RPG这种的,经常在游戏过程中需要频繁存档,在性能不好的平台上容易出各种问题,比如游戏Crash,存档丢失等等,今天想到一个可选的解法,就是用MMAP。虽然我到现在也没有搞懂这个机制究竟是怎样让程序员得到了好处,但是,至少这是一个有可能解决问题的办法。 代码: 1 #include <sy...

weixin_33772645的博客 157

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Linux内核编程--内存映射和共享内存

使用mmap时需要注意,不是所有文件都可以进行内存映射,一个访问终端或者套接字的描述符只能用read/write这类的函数去访问,用mmap做内存映射会报错。*子进程能通过fork继承存储映射区(因为子进程复制父进程地址空间,而存储映射区是该地址空间中的一部分),但是由于同样的原因,新程序则不能通过exec继承存储映射区。将用户进程的一段内存区域映射到内核进程,映射成功后,用户进程对这段内存区域的修改直接反映到内核空间,同样,内核进程对这段内存区域的修改也直接反映到用户空间。

m0_74282605的博客 216

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

C/C++ I/O性能优化:从缓冲策略到mmap的深度实践

在计算机系统中,输入输出(I/O)操作是连接应用与存储设备的关键桥梁,其性能直接影响系统整体吞吐与延迟。其核心原理在于平衡用户空间与内核空间的数据交换,通过缓冲策略减少系统调用与数据拷贝次数,以空间换时间。这一技术价值在于能显著提升后台服务、数据库等对延迟敏感系统的响应能力。应用场景广泛,涵盖日志写入、文件加载和网络传输等。本文聚焦C/C++,深入剖析标准库I/O、系统调用及内存映射(mmap)等方案,并探讨如何通过优化缓冲与访问模式来应对性能瓶颈,其中mmap通过减少数据拷贝在特定场景下表现卓越,而合理的

weixin_30256901的博客 383

C语言文件拷贝:从标准I/O到内存映射的四种实现与性能对比

文件I/O是编程中的基础概念,涉及数据在存储介质与内存间的传输。其核心原理是通过系统调用或库函数,在用户空间与内核空间之间移动数据,以完成读写操作。这项技术的价值在于它是几乎所有应用程序与操作系统交互、处理持久化数据的基石。在工程实践中,文件拷贝是检验I/O理解深度的典型场景,广泛应用于工具开发、数据处理和系统编程。本文聚焦C语言,深入探讨标准I/O、系统调用与内存映射等不同层次的实现方案,并分析其性能差异与适用场景,为开发者选择高效、健壮的拷贝策略提供决策依据。

weixin_34034261的博客 346
上一篇: MMAP和madvise的配套使用
下一篇: MPEG-4 Audio 关于esds 记录
STN_LCD
博客等级 码龄15年 384粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值