热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何使用os.posix_fadvise防止Linux上的文件缓存?

我有一个通常在整个块设备上运行的脚本,如果读取的每个块都被缓存,它将驱逐其他应用程序正在使用的数据。为了防止这种情况发生,我添加了对使用mmap(2)和posix

我有一个通常在整个块设备上运行的脚本,如果读取的每个块都被缓存,它将驱逐其他应用程序正在使用的数据。为了防止这种情况发生,我添加了对使用mmap(2)posix_fadvise(2) 的支持,逻辑如下:

指示不再需要块的函数:

def advise_dont_need(fd, offset, length):
"""
Announce that data in a particular location is no longer needed.
Arguments:
- fd (int): File descriptor.
- offset (int): Beginning of the unneeded data.
- length (int): Length of the unneeded data.
"""
# TODO: macOS support
if hasattr(os, "posix_fadvise"):
# posix_fadvise(2) states that "If the application requires that data
# be considered for discarding, then offset and len must be
# page-aligned." When this code aligns the offset and length, the
# advised area is widened under the presumption it is better to discard
# more memory than needed than to leak it which could cause resource
# issues.
# If the offset is unaligned, extend it toward 0 to align it and adjust
# the length to compensate for the change.
aligned_offset = offset - offset % PAGE_SIZE
length += offset - aligned_offset
offset = aligned_offset
# If the length is unaligned, widen it to align it.
length -= length % -PAGE_SIZE
os.posix_fadvise(fd, offset, length, os.POSIX_FADV_DONTNEED)

读取文件的逻辑:

with open(path, "rb", buffering=0) as file,
ProgressBar("Reading file") as progress, timer() as read_loop:
size = file_size(file)
if mmap_file:
# At the time of this writing, mmap.mmap in CPython uses
# st_size to determine the size of a file which will not
# work with every file type which is why file size
# autodetection (size=0) cannot be used here.
fd = file.fileno()
view = mmap.mmap(fd, size, prot=mmap.PROT_READ)
try:
while writer.error is None and hash_queue.error is None:
# Skip offsets that are already in the block map.
if offset in blocks:
while offset in blocks:
if mmap_file:
advise_dont_need(fd, offset, block_size)
offset += block_size
if not mmap_file:
file.seek(offset)
if mmap_file:
block = view[offset:offset + block_size]
advise_dont_need(fd, offset, len(block))
else:
block = file.read(block_size)
if not block:
break
bytes_read += len(block)
while hash_queue.error is None:
try:
hash_queue.put((offset, block), timeout=0.1)
offset += len(block)
progress.update(offset / size)
break
except queue.Full:
pass
finally:
if mmap_file:
view.close()

当我运行脚本并监视 的输出时free -h,尽管有这种逻辑,但我可以看到缓冲区缓存使用量增加。我的逻辑是否不正确,或者这是posix_fadvise(2)的结果——建议与授权?

以下是一些日志,显示了在 block_size 设置为 1048576 的脚本执行结束时的长度和偏移量值:

offset=107296587776; length=1048576
offset=107297636352; length=1048576
offset=107298684928; length=1048576
offset=107299733504; length=1048576
offset=107300782080; length=1048576
offset=107301830656; length=1048576
offset=107302879232; length=1048576
offset=107303927808; length=1048576
offset=107304976384; length=0


推荐阅读
  • 本文介绍了如何利用 `matplotlib` 库中的 `FuncAnimation` 类将 Python 中的动态图像保存为视频文件。通过详细解释 `FuncAnimation` 类的参数和方法,文章提供了多种实用技巧,帮助用户高效地生成高质量的动态图像视频。此外,还探讨了不同视频编码器的选择及其对输出文件质量的影响,为读者提供了全面的技术指导。 ... [详细]
  • 在最近的WWDC17大会上,苹果公司宣布了多项重要更新,其中一项是macOS High Sierra 10.13 Final的正式发布。这一版本经过优化,显著提升了系统的稳定性和响应速度,为用户在任何Mac设备上提供了更加流畅的使用体验。本文将详细介绍如何在Windows系统中利用VMware虚拟机软件安装并运行macOS High Sierra 10.13 Final,帮助用户在非苹果硬件上体验这一先进操作系统。 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • Framework7:构建跨平台移动应用的高效框架
    Framework7 是一个开源免费的框架,适用于开发混合移动应用(原生与HTML混合)或iOS&Android风格的Web应用。此外,它还可以作为原型开发工具,帮助开发者快速创建应用原型。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 在《Linux高性能服务器编程》一书中,第3.2节深入探讨了TCP报头的结构与功能。TCP报头是每个TCP数据段中不可或缺的部分,它不仅包含了源端口和目的端口的信息,还负责管理TCP连接的状态和控制。本节内容详尽地解析了TCP报头的各项字段及其作用,为读者提供了深入理解TCP协议的基础。 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 为了在Hadoop 2.7.2中实现对Snappy压缩和解压功能的原生支持,本文详细介绍了如何重新编译Hadoop源代码,并优化其Native编译过程。通过这一优化,可以显著提升数据处理的效率和性能。此外,还探讨了编译过程中可能遇到的问题及其解决方案,为用户提供了一套完整的操作指南。 ... [详细]
  • 深入解析Android 4.4中的Fence机制及其应用
    在Android 4.4中,Fence机制是处理缓冲区交换和同步问题的关键技术。该机制广泛应用于生产者-消费者模式中,确保了不同组件之间高效、安全的数据传输。通过深入解析Fence机制的工作原理和应用场景,本文探讨了其在系统性能优化和资源管理中的重要作用。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 本文详细介绍了在Linux系统上编译安装MySQL 5.5源码的步骤。首先,通过Yum安装必要的依赖软件包,如GCC、GCC-C++等,确保编译环境的完备。接着,下载并解压MySQL 5.5的源码包,配置编译选项,进行编译和安装。最后,完成安装后,进行基本的配置和启动测试,确保MySQL服务正常运行。 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • 在Android应用开发中,实现与MySQL数据库的连接是一项重要的技术任务。本文详细介绍了Android连接MySQL数据库的操作流程和技术要点。首先,Android平台提供了SQLiteOpenHelper类作为数据库辅助工具,用于创建或打开数据库。开发者可以通过继承并扩展该类,实现对数据库的初始化和版本管理。此外,文章还探讨了使用第三方库如Retrofit或Volley进行网络请求,以及如何通过JSON格式交换数据,确保与MySQL服务器的高效通信。 ... [详细]
author-avatar
王怡君3018
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有