当前位置: 首页 > article >正文

Rust 中 `madvise` 和 `posix_fadvise`的区别

在 Linux 操作系统中,madviseposix_fadvise 是两个用于内存管理的系统调用,它们提供了一些类似的功能,但也有一些关键的区别。以下是它们的详细对比:

madvise

madvise 是一个系统调用,用于向内核提供关于应用程序如何使用一段内存区域的建议。定义如下:

int madvise(void *addr, size_t length, int advice);
参数说明:
  • addr:指向内存区域的起始地址。
  • length:内存区域的长度。
  • advice:建议的类型,决定了内核如何管理这段内存。这些建议包括:
    • MADV_NORMAL: 默认的内存访问行为。
    • MADV_SEQUENTIAL: 预期顺序访问。
    • MADV_RANDOM: 预期随机访问。
    • MADV_WILLNEED: 预期将会需要这段内存,内核应尽早加载。
    • MADV_DONTNEED: 预期不再需要这段内存,内核可以释放。
    • 其他更多的建议类型。

posix_fadvise

posix_fadvise 是一个 POSIX 标准的函数,用于向内核提供关于文件访问模式的建议。定义如下:

int posix_fadvise(int fd, off_t offset, off_t len, int advice);
参数说明:
  • fd:文件描述符,表示要操作的文件。
  • offset:文件中的起始偏移量。
  • len:建议操作的字节数。
  • advice:建议的类型,决定了内核如何管理文件的缓存。这些建议包括:
    • POSIX_FADV_NORMAL: 默认的文件访问行为。
    • POSIX_FADV_SEQUENTIAL: 预期顺序访问。
    • POSIX_FADV_RANDOM: 预期随机访问。
    • POSIX_FADV_WILLNEED: 预期将会需要这部分文件,内核应尽早加载。
    • POSIX_FADV_DONTNEED: 预期不再需要这部分文件,内核可以释放。
    • POSIX_FADV_NOREUSE: 预期这部分文件不会被再次访问。

区别与应用场景

  1. 作用对象

    • madvise 作用于内存区域。它主要用于优化内存管理,适用于内存映射文件或匿名内存。
    • posix_fadvise 作用于文件。它主要用于优化文件 I/O 操作,适用于文件访问模式的优化。
  2. 建议类型

    • 两者的建议类型有一些重叠,比如 SEQUENTIALRANDOM,但也有一些独特的建议类型。例如,madviseMADV_DONTNEED 可以用来释放内存,而 posix_fadvisePOSIX_FADV_NOREUSE 可以用来表示不再重用这部分文件。
  3. 标准与兼容性

    • madvise 是 Linux 特有的系统调用,是 Linux 内核 API 的一部分。
    • posix_fadvise 是 POSIX 标准的一部分,因而具有更广泛的可移植性,适用于遵循 POSIX 标准的操作系统。
  4. 使用场景

    • 使用 madvise 的典型场景是对内存映射文件的优化和管理,例如数据库管理系统在管理内存映射的数据库文件时。
    • 使用 posix_fadvise 的典型场景是对文件 I/O 的优化,例如在大数据处理过程中对文件的顺序或随机访问进行优化。

示例代码

以下是一个使用 madviseposix_fadvise 的示例:

使用 madvise
use std::fs::OpenOptions;
use std::io;
use std::os::unix::io::AsRawFd;
use mmap2::{Mmap, MmapOptions};
use nix::sys::mman::{madvise, MmapAdvise};

fn use_madvise(path: &str, len_of_range: usize, offset: i64) -> Result<(), io::Error> {
    let file = OpenOptions::new().read(true).open(path)?;
    let mmap = unsafe {
        MmapOptions::new()
            .len(len_of_range)
            .offset(offset as u64)
            .map(&file)?
    };
    let mem = mmap.as_ptr();

    // Provide advice to the kernel about the memory usage
    let ret = unsafe { madvise(mem, len_of_range, MmapAdvise::MADV_SEQUENTIAL) };
    if let Err(err) = ret {
        eprintln!("unable to madvise file {} ({})", path, err);
    }

    Ok(())
}
使用 posix_fadvise
use std::fs::OpenOptions;
use std::io;
use std::os::unix::io::AsRawFd;
use nix::fcntl::{posix_fadvise, PosixFadviseAdvice};

fn use_posix_fadvise(path: &str, len_of_range: usize, offset: i64) -> Result<(), io::Error> {
    let file = OpenOptions::new().read(true).open(path)?;
    let fd = file.as_raw_fd();

    // Provide advice to the kernel about the file access
    let ret = posix_fadvise(fd, offset, len_of_range as i64, PosixFadviseAdvice::POSIX_FADV_SEQUENTIAL);
    if let Err(err) = ret {
        eprintln!("unable to posix_fadvise file {} ({})", path, err);
    }

    Ok(())
}

http://www.kler.cn/a/292831.html

相关文章:

  • 2024年11月12日Github流行趋势
  • 【HarmonyOS NEXT】一次开发多端部署(以轮播图、Tab栏、列表为例,配合栅格布局与媒体查询,进行 UI 的一多开发)
  • C# 模拟浏览器自操作(自动化办公)
  • Qt 和 WPF(Windows Presentation Foundation)
  • 文件夹被占用了无法删除怎么办?强制粉碎文件夹你可以这样操作
  • L10.【LeetCode笔记】回文链表
  • python文件自动化(4)
  • 了解一下HTTP 与 HTTPS 的区别
  • FP7195:非同步升压恒流LED区动IC
  • C#实战|大乐透选号器[3]:动态生成大乐透蓝球区选择球及实现拖动窗体功能
  • Flask+LayUI开发手记(六):树型表格的增删改查
  • 网络编程 0905作业
  • 在ABAP开发中,BSEG和BKPF的数据如何做关联查询?
  • Unity(2022.3.41LTS) - UI详细介绍-TMP
  • WordPress的安装与简单开发教程
  • springboot 配置ssl支持https
  • 软通动力子公司鸿湖万联重磅发布SwanLinkOS 5,擘画开源鸿蒙AI PC新篇章
  • 七、装饰器模式
  • 薄膜制造革新-平扫式自动风环测厚仪
  • 基于 Python 的 LIF 模型:探索神经元同步与小世界网络
  • Ubuntu20上的Qt程序连接Windows上的mssql服务器
  • Tableau 社区项目 | 参与 Data+TV 挑战,洞悉全球电视剧集数据的精彩故事!
  • vue3获取视频时长、码率、格式等视频详细信息
  • pytorch torch.squeeze函数介绍
  • 2024年高教社杯全国大学生数学建模竞赛A题思路(2024数学建模国赛A题思路)
  • Flutter 局部变量刷新问题