Go mmap 文件内存映射

这篇具有很好参考价值的文章主要介绍了Go mmap 文件内存映射。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Go mmap 文件内存映射

mmap是个很好用的内存映射工具,它可以将文件映射到内存中,可以方便地操作文件。使用mmap的优点是:

  • 内存映射可以使得读写文件的性能更高,因为操作的是内存而不是磁盘。
  • 可以方便地操作文件,不需要再通过文件操作的方式打开读写文件。
  • 方便多线程操作文件。

Go mmap 文件内存映射

优点

mmap 另一个非常重要的特性是:减少内存的拷贝次数。在 linux 系统中,文件的读写操作通常通过 read 和 write 这两个系统调用来实现,这个过程会产生频繁的内存拷贝。比如 read 函数就涉及了 2 次内存拷贝:文章来源地址https://www.toymoban.com/news/detail-494479.html

  • 操作系统读取磁盘文件到页缓存
  • 从页缓存将数据拷贝到 read 传递的 buf 中
    mmap 只需要一次拷贝。即操作系统读取磁盘文件到页缓存,进程内部直接通过指针方式修改映射的内存。因此 mmap 特别适合读写频繁的场景,既减少了内存拷贝次数,提高效率,又简化了操作。KV数据库 bbolt 就使用了这个方法持久化数据。

例子

package main
 
import (
    "fmt"
    "log"
    "os"
    "syscall"
    "unsafe"
)
 
const defaultMaxFileSize = 1 << 30        // 假设文件最大为 1G
const defaultMemMapSize = 128 * (1 << 20) // 假设映射的内存大小为 128M
 
func main() {
    mmpFile := NewMmpFile("test.txt")
    defer mmpFile.munmap()
    defer mmpFile.file.Close()
    msg := "hello csdn colinrs!"
 
    mmpFile.grow(int64(len(msg) * 2))
    for i, v := range msg {
        mmpFile.data[i] = byte(v)
    }
}
 
type MmpFile struct {
    file    *os.File
    data    *[defaultMaxFileSize]byte
    dataRef []byte
}
 
func NewMmpFile(fileName string) *MmpFile {
    file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0666)
    if err != nil {
        log.Fatalf("Open file error: %v", err)
    }
    mmpFile := &MmpFile{file: file}
    mmpFile.mmap()
    return mmpFile
}
 
func _assert(condition bool, msg string, v ...interface{}) {
    if !condition {
        panic(fmt.Sprintf(msg, v...))
    }
}
 
func (mmpFile *MmpFile) mmap() {
    b, err := syscall.Mmap(int(mmpFile.file.Fd()), 0,
        defaultMemMapSize, syscall.PROT_WRITE|syscall.PROT_READ, syscall.MAP_SHARED)
    _assert(err == nil, "failed to mmap", err)
    mmpFile.dataRef = b
    mmpFile.data = (*[defaultMaxFileSize]byte)(unsafe.Pointer(&b[0]))
}
 
func (mmpFile *MmpFile) grow(size int64) {
    if info, _ := mmpFile.file.Stat(); info.Size() >= size {
        return
    }
    _assert(mmpFile.file.Truncate(size) == nil, "failed to truncate")
}
 
func (mmpFile *MmpFile) munmap() {
    _assert(syscall.Munmap(mmpFile.dataRef) == nil, "failed to munmap")
    mmpFile.data = nil
    mmpFile.dataRef = nil
}
  • 遇到 mmp 文件报错为 syscall.Errno=permission denied),
    • 可以参考:syscall.Errno=permission denied)
    • 将读取文件修改为 os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0666)

参考

  • Go Mmap 文件内存映射简明教程
  • 阅读笔记:零拷贝及一些引申内容

到了这里,关于Go mmap 文件内存映射的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux 共享内存mmap,进程通信

    进程间通信是操作系统中重要的概念之一,使得不同的进程可以相互交换数据和进行协作。其中,共享内存是一种高效的进程间通信机制,而内存映射(mmap)是实现共享内存的一种常见方法。 存储映射 I/O 是 一个磁盘文件 与 存储空间中的一个缓冲区相映射 。于是, 当从缓

    2024年02月13日
    浏览(26)
  • C++ CreateFileMapping 内存映射实现快速读取文件

    共享内存的方式原理就是将一份物理内存映射到不同进程各自的虚拟地址空间上,这样每个进程都可以读取同一份数据,从而实现进程通信。因为是通过内存操作实现通信,因此是一种最高效的数据交换方法。 本文主要讲述的使用内存映射文件的目的是访问磁盘上的数据文件

    2023年04月09日
    浏览(23)
  • 浅聊一下 C#程序的 内存映射文件 玩法

    前段时间训练营里有朋友问 内存映射文件 是怎么玩的?说实话这东西理论我相信很多朋友都知道,就是将文件映射到进程的虚拟地址,说起来很容易,那如何让大家眼见为实呢?可能会难倒很多人,所以这篇我以自己的认知尝试让大家眼见为实。 在任何讨论之前,内存文件

    2024年02月08日
    浏览(25)
  • 10 Go的映射

    概述         在上一节的内容中,我们介绍了Go的结构体,包括:定义结构体、声明结构体变量、使用结构体、结构体关联函数、new、组合等。在本节中,我们将介绍Go的映射。Go语言中的映射(Map)是一种无序的键值对集合,使用map来声明,并使用键和值类型作为

    2024年02月04日
    浏览(20)
  • 用户态内存映射

    内存映射不仅仅是物理内存和虚拟内存之间的映射,还包括将文件中的内容映射到虚拟内存空间。这个时候,访问内存空间就能够访问到文件里面的数据。而仅有物理内存和虚拟内存的映射,是一种特殊情况。 对于堆的申请来讲,mmap 是映射内存空间到物理内存。 如果一个进

    2024年02月05日
    浏览(22)
  • C++ 内存映射

      在一个版图集成与分析工具的项目中看到了 一种 C++ 内存映射的用法,觉得非常强,分享一下大致的概念。   随着制造工艺的不断进步,芯片版图文件越来越大,对于一些很大的文件,可能光是打开就需要几个小时,是芯片设计开发人员的一大痛点。   于是我们领

    2024年02月13日
    浏览(23)
  • 乐鑫 SoC 内存映射入门

    微控制器 (MCU) 的性能和内存能力逐步提升,其复杂度也随之加大。特别是当用户需要配置内存管理单元来映射外部存储器芯片 (Flash/SPIRAM) 时,这种现象尤其明显。 开始在乐鑫 SoC 上运行 Zephyr RTOS 时,会发现这些 SoC 与 ARM 架构的 MCU 相比,完全是不同的世界。ARM Cortex-M 基于冯

    2024年02月08日
    浏览(31)
  • DS/ML:模型全流程优化之系统优化—替代Pandas库的大数据高效处理技术优化集合如HDF5技术(压缩文件)+vaex库(内存映射)+dask库(集群技术)替代pandas的各自骚操作实现代码

    DS/ML:模型全流程优化之系统优化—替代Pandas库的大数据高效处理技术优化集合如HDF5技术(压缩文件)+vaex库(内存映射)+dask库(集群技术)替代pandas的各自骚操作实现代码 目录

    2024年02月09日
    浏览(34)
  • 【Go 基础篇】Go语言结构体之间的转换与映射

    在Go语言中,结构体是一种强大的数据类型,用于定义和组织不同类型的数据字段。当我们处理复杂的数据逻辑时,常常需要在不同的结构体之间进行转换和映射,以便实现数据的转移和处理。本文将深入探讨Go语言中结构体之间的转换和映射技巧,包括类型转换、自定义转换

    2024年02月10日
    浏览(29)
  • Go语言程序设计(六)字典(映射)

            在Go语言中,Map是一种特殊的数据结构,它由一对无序的数据项组成,被称为键值对(Key-value Pair)。其中的一项是键(Key),另外一项是值(Value), Map通过把键映射到值来进行访问,这种方式可以加快数据查找的速度。所以,Map通常也被称作字典(Dictionary)或哈希表(Hash table) ,本

    2024年02月12日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包