写入内存映射文件后,什么会更新 mtime?

2024-02-10

我在 Linux 上使用 XFS,并且有一个内存映射文件,每秒写入一次。我注意到文件 mtime (由watch ls --full-time) 周期性但不规则地变化。 mtimes之间的差距似乎在2到20秒之间,但并不一致。系统上几乎没有其他东西在运行——特别是我的程序只有一个写入文件,再加上一个读取文件。

同一个程序更频繁地写入其他一些映射文件,并且它们的 mtime 每 30 秒更改一次。

我没有使用msync()(调用时会更新 mtime)。

我的问题:

  1. mtime 更新了什么?
  2. 更新间隔可以配置吗?
  3. 为什么有些 mtime 每 30 秒更新一次,但有些我写入频率较低的文件却有更新鲜的(不规则但总是小于 30 秒)mtime?

当你mmap一个文件,基本上是在进程和内核的页面缓存之间直接共享内存——该缓存保存已从磁盘读取或等待写入磁盘的文件数据。页面缓存中与磁盘上的页面不同(因为它已被写入)的页面被称为“脏”页面。

有一个内核线程在几个参数的控制下扫描脏页并将其写回磁盘。其中一个重要的就是dirty_expire_centisecs。如果文件的任何页面脏的时间超过dirty_expire_centisecs那么该文件的所有脏页都将被写出。默认值为 3000 厘秒(30 秒)。

另一组变量是dirty_writeback_centisecs, dirty_background_ratio, and dirty_ratio. dirty_writeback_centisecs控制内核线程检查脏页的频率,默认为 500(5 秒)。如果脏页的百分比(作为可用于缓存的内存的一部分)小于dirty_background_ratio然后什么也没有发生;如果超过dirty_background_ratio,然后内核将开始将一些页面写入磁盘。最后,如果脏页百分比超过dirty_ratio,那么任何尝试写入的进程都会阻塞,直到脏数据量减少。这样保证了未写入的数据量不会无限制的增加;最终,产生数据的速度快于磁盘写入速度的进程将不得不放慢速度以匹配磁盘的速度。

mtime 如何更新的问题首先与内核如何知道页面是脏的问题相关。如果是mmap,答案是内核将映射的页面设置为只读。这并不意味着您不能编写它们,而是意味着第一次这样做时,它会触发内存管理单元中的异常,该异常由内核处理。异常处理程序(至少)做了四件事:

  1. 将页面标记为脏页,以便将其写回。
  2. 更新文件 mtime.
  3. 将页面标记为可读写,以便写入能够成功。
  4. 跳回到程序中写入的指令mmaped 页面,这次成功了。

So when you write data to a clean page, it causes an mtime update, but it also causes the page to become read-write, so that further writes don't cause an exception (or an mtime update)note 1. However, when the dirty page gets flushed to disk, it becomes clean, and also becomes "read-only" again, so that any further writes to it will trigger another eventual disk write, and also another mtime update.

现在,通过一些假设,我们可以开始拼凑这个难题。

First, dirty_background_ratio and dirty_ratio可能不会发挥作用。如果您的写入速度足够快以触发后台刷新,那么您很可能会在所有文件上看到“不规则”行为。

其次,“不规则”文件和“30秒”文件之间的区别在于页面访问模式。我推测“不规则”文件是以某种追加模式或循环缓冲区方式写入的,这样您就开始每隔几秒写入一个新页面。每次弄脏之前未触及的页面时,都会触发一次实时更新。但对于显示 30 秒模式的文件,您只能写入一页(也许它们的长度为一页或更短)。在这种情况下,mtime 在第一次写入时更新,然后不会再次更新,直到文件刷新到磁盘超过dirty_expire_centisecs,即 30 秒。

Note 1:从技术上讲,这种行为是错误的。这是不可预测的,但标准允许一定程度的不可预测性。但他们确实要求 mtime 是某个时间最后一次写入时或之后到一个文件,并且在msync(如果有的话)。如果页面在刷新到磁盘之前的时间间隔内被多次写入,则不会发生这种情况 - mtime 获取该页面的时间戳first写。这已经讨论过了,但是一个可以修复它的补丁 https://lwn.net/Articles/564120/没有被接受。因此,当使用mmap,m次可能会出错。dirty_expire_centisecs某种程度上限制了该错误,但只是部分限制,因为其他磁盘流量可能会导致刷新必须等待,从而进一步延长写入时间以绕过 mtime。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

写入内存映射文件后,什么会更新 mtime? 的相关文章

  • 为什么我收到的数据包数据大小大于mss?

    我在两台 PC 上使用 ifconfig ethX mtu 300 修改了 MTU 并使用 netperf 测试网络 我用 WireShark 嗅探了 SYN 数据包中的 MSS 260 但我得到了一些大于 260 的数据包 为什么 嗅探器
  • Unix 命令列出包含字符串但*不*包含另一个字符串的文件

    如何递归查看包含一个字符串且不包含另一个字符串的文件列表 另外 我的意思是评估文件的文本 而不是文件名 结论 根据评论 我最终使用了 find name html exec grep lR base maps xargs grep L ba
  • 在 Linux 上更快地分叉大型进程?

    在现代 Linux 上达到与 Linux 相同效果的最快 最好的方法是什么 fork execve combo 从一个大的过程 我的问题是进程分叉大约 500MByte 大 并且一个简单的基准测试只能从进程中实现约 50 个分叉 秒 比较最
  • 通过特定分隔符删除字符串

    我的文件中有几列 其中第二列有 分隔符 我想删除第二列中的第一个 第三个和第四个字符串 并将第二个字符串留在该列中 但我有正常的分隔符空间 所以我不知道 input 22 16050075 A G 16050075 A G 22 16050
  • 使用 grep 查找包含所有搜索字符串的行

    我有一个文件 其中包含很多与此类似的行 id 2796 some model Profile message type MODEL SAVE fields account 14 address null modification times
  • 为什么内核需要虚拟寻址?

    在Linux中 每个进程都有其虚拟地址空间 例如 32位系统为4GB 其中3GB为进程保留 1GB为内核保留 这种虚拟寻址机制有助于隔离每个进程的地址空间 对于流程来说这是可以理解的 因为有很多流程 但既然我们只有 1 个内核 那么为什么我
  • 无法从 jenkins 作为后台进程运行 nohup 命令

    更新 根据下面的讨论 我编辑了我的答案以获得更准确的描述 我正在尝试从詹金斯运行 nohup 命令 完整的命令是 nohup java jar home jar server process 0 35 jar prod gt gt var
  • 使用 sed 更新 xml 属性(Windows + cygwin 和 Linux)?

    我需要使用 sed 命令对 xml 文件进行更新 但我在这方面遇到了麻烦 它需要在 Windows 使用 cygwin 和 Linux 上运行 XML 具有以下元素
  • Linux 中的动态环境变量?

    Linux 中是否可以通过某种方式拥有动态环境变量 我有一个网络服务器 网站遵循以下布局 site qa production 我想要一个环境变量 例如 APPLICATION ENV 当我在 qa 目录中时设置为 qa 当我在生产目录中时
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • arm64和armhf有什么区别?

    Raspberry Pi Type 3 具有 64 位 CPU 但其架构不是arm64 but armhf 有什么区别arm64 and armhf armhf代表 arm hard float 是给定的名称Debian 端口 https
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 无法使用 wget 在 CentOS 机器上安装 oracle jdk

    我想在CentOS上安装oracle java jdk 8 我无法安装 java jdk 因为当我尝试使用命令安装 java jdk 时 root ADARSH PROD1 wget no cookies no check certific
  • 如何在 Linux shell 中将十六进制转换为 ASCII 字符?

    假设我有一个字符串5a 这是 ASCII 字母的十六进制表示Z 我需要找到一个 Linux shell 命令 它将接受一个十六进制字符串并输出该十六进制字符串代表的 ASCII 字符 所以如果我这样做 echo 5a command im
  • 如何将目录及其子目录中的所有 PDF 文件复制到一个位置?

    如何全部复制PDF文件从目录及其子目录到单个目录 实际上还有更多的文件 并且深度有些任意 假设四个目录的最大深度是公平的 我想这些文件需要重命名 如果a pdf例如 位于多个目录中 因为我会adding https ebooks stack
  • Linux 内核标识符中前导和尾随下划线的含义是什么?

    我不断遇到一些小约定 比如 KERNEL Are the 在这种情况下 是内核开发人员使用的命名约定 还是以这种方式命名宏的语法特定原因 整个代码中有很多这样的例子 例如 某些函数和变量以 甚至 这有什么具体原因吗 它似乎被广泛使用 我只需
  • NPTL 和 POSIX 线程有什么区别?

    NPTL 和 POSIX 线程之间的基本区别是什么 这两者是如何演变的 POSIX 线程 pthread 不是一个实现 它是几个函数的 API 规范 纸上的标准 英文 其名称以pthread 以及定义在
  • Linux:在文件保存时触发 Shell 命令

    我想在修改文件时自动触发 shell 命令 我认为这可以通过注册 inotify 挂钩并调用来在代码中完成system 但是是否有更高级别的 bash 命令可以完成此任务 尝试 inotify 工具 我在复制链接时遇到问题 抱歉 但 Git
  • Linux 可执行文件与 OS X“兼容”吗?

    如果您在基于 Linux 的平台上用 C 语言编译一个程序 然后将其移植以使用 MacOS 库 它会工作吗 来自编译器的核心机器代码在 Mac 和 Linux 上兼容吗 我问这个问题的原因是因为两者都是 基于 UNIX 的 所以我认为这是真
  • PHP 脚本不断执行 mmap/munmap

    我的 PHP 脚本包含一个循环 它只不过是回显和取消引用指针 如 tab othertab i gt 中的内容 直到昨天 这个脚本开始变得非常慢 比以前慢了 50 倍 之前 它一直运行良好 使用 strace 后 我发现 90 的情况下 脚

随机推荐

  • NoClassDefFoundError是如何抛出的

    我在 eclipse 中构建了一个名为 com hello 的包 并编写了一个简单的 HelloWorld 程序 Eclipse 自动添加了 package com hello 在我的程序之上 并且HelloWorld java被放入 F
  • python-将用户输入转换为整数格式时遇到问题

    user input Enter a number and I will tell you the sum of the multiples of 3 and 5 leading up to it number int user input
  • Apache HttpClient 4.1 - 代理身份验证

    我一直在尝试使用 Apache HttpComponent 的 httpclient 时从配置的属性配置代理身份验证的用户和密码 但没有成功 我发现的所有示例都引用了不再可用的方法和类 例如HttpState and setProxyCre
  • 如何观察 Vue.js 组件中 prop 的变化?

    我将图像文件路径数组传递给组件 我想知道如果我传递不同的数组 在 Vue js 组件中观察 prop 更改的最佳方式是什么 我正在使用引导轮播 所以想在数组更改时将其重置为第一个图像 为了简单起见 我将代码示例简化为 Vue compone
  • Chrome 如何检测信用卡字段?

    在某些表单中 Chrome 自动填充会提示信用卡自动填充 编辑 添加屏幕截图 这与浏览器自动完成不同 您之前不必以相同的形式输入该值 我应该如何编写 HTML 表单 以便浏览器将其检测为信用卡字段并触发此行为 与 Stripe 表单一起使用
  • 从 SVG 矩形元素获取每个像素的 RGB 值

    我需要获取 svg 矩形元素中每个像素的颜色值 在 canvas 中我们可以通过方法 getImageData x y width height 获取它 在svg中 有什么方法可以做到这一点吗 如果是的话请给出一些工作示例 如果您创建一个独
  • 从 Wordpress 创建关联数组 $wpdb->get_results

    这是漫长的一天 出于某种原因 这完全让我无法理解 我的 WordPress 数据库请求如下所示 results wpdb gt get results sql 输出看起来像这样 Array 0 gt stdClass Object id g
  • 选择默认值后,Android Complete 操作会继续显示

    我在应用程序开发中遇到了一个奇怪的问题 在我的应用程序中的某个时刻 它会调用 Intent Intent ACTION SEND 来启动 Gmail 将出现 使用 完成操作 对话框 即使我选中底部的默认框并选择 Gmail 下次我的应用程序
  • 离子电容器:错误:未在网络上实现

    完成迁移后cordova to capacitor 运行时出现以下错误ionic s Error vendor js 114293 ERROR Error Uncaught in promise Error Not implemented
  • 找不到类“android.support.v4.widget.SwipeRefreshLayout”[重复]

    这个问题在这里已经有答案了 我不断收到此错误 它导致我的应用程序崩溃 尝试实现新的 v4 滑动刷新布局 我已经更新了支持库 sdk 问题是什么 找不到类 android support v4 widget SwipeRefreshLayou
  • 如何使用 boost.python 公开对齐的类

    当尝试像这样公开对齐的类时 class declspec align 16 foo public void foo method BOOST PYTHON MODULE foo module class
  • GWT 中共享包的重要性

    我意识到 GWt 不会编译不在客户端包中的类 但共享包的重要性是什么 我需要在这个包中放入哪些类 我需要上哪些课程 放入这个包中 客户端和服务器都使用的任何逻辑或数据类型 这将使您免于复制双方的代码 并可能保留逻辑和数据类型持续的
  • HttpRequestMessage 内容中的文件名

    我实现了 POST Rest 服务来将文件上传到我的服务器 我现在遇到的问题是我想按类型限制上传的文件 举例来说 我只想允许上传 pdf 文件 我试图做的是 Task
  • 从 Eclipse 菜单 Window -> Show View 中删除视图名称

    我需要删除从 窗口 gt 显示视图 菜单创建的视图的名称 快捷方式 并将它们添加为单独的菜单 有什么方法可以从 窗口 gt 显示视图 菜单中隐藏 删除其条目 您可以从 自定义透视 菜单可见性 选项卡的 显示视图 菜单中添加 删除任何视图 以
  • docker在aws ecs中运行程序参数

    我在 Amazon 的 ECS 中有一个工作容器 它将程序作为任务运行 我想传递一些程序参数 就像我在本地运行时所做的那样docker run 我已经成功地在 ECS 的容器配置中传递了一个新的入口点 就像我在docker run命令行 不
  • 由于定义顺序,常量初始化“令人惊讶”

    阅读时关于 constexpr 的幻灯片 http accu org content conf2007 Maurer C 0x Generating Constant Expression pdf简介是关于 使用 const 进行令人惊讶的
  • 在C语言中连接字符串,哪种方法更有效?

    我遇到了这两种连接字符串的方法 共同部分 char first First char second Second char both malloc strlen first strlen second 2 方法一 strcpy both f
  • Apple Watch:状态栏高度

    有人知道 Apple Watch 状态栏的大小吗 无论是在 Apple Watch 人机界面指南还是 Apple Watch 编程指南中 我都无法在文档中找到这样的价值 所以 我已经测量过它们了 38mm 19pt 38px 42mm 21
  • char* - 为什么指针中没有地址?

    我有一个基本问题char 我不明白 char aString Hello Stackoverflow 指针指向字符链的第一个字符 cout lt lt aString H 但为什么整个字符串都保存在指针中呢 cout lt lt aStri
  • 写入内存映射文件后,什么会更新 mtime?

    我在 Linux 上使用 XFS 并且有一个内存映射文件 每秒写入一次 我注意到文件 mtime 由watch ls full time 周期性但不规则地变化 mtimes之间的差距似乎在2到20秒之间 但并不一致 系统上几乎没有其他东西在