我正在使用我在Linux中的Direct Memory Access上发布的驱动程序将一些物理ram映射到用户空间地址.但是,我无法使用GDB来查看任何地址; 即,x 0x12345678(其中0x12345678是mmap的返回值)失败,并显示错误"无法访问地址0x12345678处的内存".
有没有办法告诉GDB可以查看这个内存?或者,我在mmap中可以做些什么(在foo_mmap的调用或实现),它将允许它访问这个内存?
请注意,我不是在询问/ dev/mem(如在那里的第一个片段中),而是关于通过ioremap(),virt_to_phys()和remap_pfn_range()获取的内存的mmap
我花了一些时间研究我正在处理的应用程序的内存映射IO.我有一些非常大的(TB级)文件,我想将它们的段映射到内存中,用于读取和写入,最大限度地利用操作系统级缓存.我正在编写的软件需要在Unix/Linux和Windows下运行......性能至关重要.
我发现boost::iostreams::mapped_file_source和boost::iostreams::mapped_file_sink,其提供了大部分我在寻找的设施.我喜欢但尚未找到的设施是:
msync在Unix FlushViewOfFile上为(2); 在Windows上)我可以使用这些东西"boost/iostreams/device/mapped_file.hpp"吗?是否有其他独立于平台的库可以更好地满足我的要求?我必须开发自己的跨平台库才能获得这种灵活性吗?
Helllo,我想在python和进程之间共享少量数据(<1K).数据是物理pc/104 IO数据,它们经常快速变化(24x7x365).将有一个"服务器"写入数据,多个客户端读取它的一部分.这将运行的系统使用闪存(CF卡)而不是硬盘驱动器,所以我担心使用基于文件的方案磨损闪存.我也希望使用更少的功率(处理器时间),因为我们100%太阳能供电.
谢谢
更新:我们将最大数据更新速率降低到大约10 Hz,但更典型的是1 Hz.客户端仅在值更改时通知,而不是以不断更新的速率通知.我们已经进入了多服务器/多客户端模型,其中每个服务器都专注于某种类型的仪器或功能.由于事实证明大部分编程都是由Java程序员完成的,我们最终使用的是JSON-RPC over TCP.服务器将用Java编写,但我仍然希望用Python编写主客户端并调查JSON-RPC实现.
假设我使用/ dev/zero为mmap分配一个大内存(40MB),如下所示.
fd = open("/dev/zero", O_RDWR);
a = mmap (0, 4096e4, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0);
Run Code Online (Sandbox Code Playgroud)
我的理解是,当页面被带入物理内存时,内核会将内存初始化为零(我认为现代Linux内核使用Demand分页).因此,例如,当第一页被触摸并因此被带入物理存储器时,内核将其所有4096字节初始化为零,然后当触摸第二页时,它执行相同的操作,依此类推.
我的理解是否正确?
我正在编写一个程序,它从网络接收大量数据(不同大小的数据),处理它们并将它们写入内存.由于某些数据可能非常大,我目前的方法是限制使用的缓冲区大小.如果一个片段大于最大缓冲区大小,我将数据写入临时文件,然后以块的形式读取文件以进行处理和永久存储.
我想知道这是否可以改善.我一直在阅读关于mmap的一段时间,但我不是百分百肯定它是否可以帮助我.我的想法是使用mmap来读取临时文件.这有什么用?我担心的主要问题是,偶尔的大块数据不应该填满我的主内存,导致其他所有内容都被换掉.
另外,您认为临时文件的方法是否有用?我是否应该这样做,或者,或许,我应该相信Linux内存管理器为我做这项工作?或者我应该完全做其他事情?
编者注:此代码示例来自1.0之前的Rust版本,它使用的代码在Rust 1.0中不存在.一些答案已经更新,以回答更新版本的Rust的核心问题.
我正在尝试使用创建内存映射文件std::os::MemoryMap.目前的方法如下:
use std::os;
use std::ptr;
use std::old_io as io;
use std::os::unix::prelude::AsRawFd;
use std::os::MapOption;
let path = Path::new("test.mmap");
let f = match io::File::open_mode(&path, io::Open, io::ReadWrite) {
Ok(f) => f,
Err(err) => panic!("Could not open file: {}", err),
};
let mmap_opts = &[
MapOption::MapReadable,
MapOption::MapWritable,
MapOption::MapFd(f.as_raw_fd())
];
let mmap = match os::MemoryMap::new(1024*1024, mmap_opts) {
Ok(mmap) => {
println!("Successfully created the mmap: {}", mmap.len());
mmap
}
Err(err) => panic!("Could not read the mmap: {}", err),
};
unsafe {
let …Run Code Online (Sandbox Code Playgroud) 我想在Linux机器使用的大页面上分配内存.我看到有两种方法可以做到这一点,使用mmap和madvise.
也就是说,使用MAP_HUGETLB带有mmap调用的标志-
base_ptr_ = mmap(NULL, memory_size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
Run Code Online (Sandbox Code Playgroud)
和呼号的MADV_HUGEPAGE旗帜madvise-
madvise(base_ptr_, memory_size_, MADV_HUGEPAGE);
Run Code Online (Sandbox Code Playgroud)
有人可以解释两者之间的区别吗?
我有一个嵌入式 ARM Linux 机器,其 RAM 量有限(512MB)且没有交换空间,我需要在其上创建然后操作一个相当大的文件(~200MB)。将整个文件加载到 RAM 中,修改 RAM 中的内容,然后再次将其写回,有时会调用 OOM-killer,我想避免这种情况。
我解决这个问题的想法是使用mmap()这个文件映射到我的进程的虚拟地址空间;这样,对映射内存区域的读取和写入将转到本地闪存文件系统,并且可以避免 OOM 杀手,因为如果内存不足,Linux 可以只刷新一些 mmap() 的内存页回到磁盘以释放一些 RAM。(这可能会使我的程序变慢,但对于这个用例来说慢是可以的)
但是,即使有mmap()调用,我仍然偶尔会看到进程在执行上述操作时被 OOM-killer 杀死。
我的问题是,我是否对 Linux 在同时存在大型 mmap() 和有限 RAM 的情况下的行为过于乐观?(即 mmap()-ing 一个 200MB 的文件,然后读/写到 mmap() 的内存仍然需要 200MB 的可用 RAM 才能可靠地完成?)或者 mmap() 是否应该足够聪明以分页出 mmap 的页面当内存不足时,但我在使用它时做错了什么?
FWIW我做映射的代码在这里:
void FixedSizeDataBuffer :: TryMapToFile(const std::string & filePath, bool createIfNotPresent, bool autoDelete)
{
const int fd = open(filePath.c_str(), (createIfNotPresent?(O_CREAT|O_EXCL|O_RDWR):O_RDONLY)|O_CLOEXEC, S_IRUSR|(createIfNotPresent?S_IWUSR:0));
if (fd >= 0)
{
if ((autoDelete == false)||(unlink(filePath.c_str()) == 0)) // so the …Run Code Online (Sandbox Code Playgroud) 我得到了一些我需要解析的大文件,人们一直在推荐mmap,因为这样可以避免在整个内存中分配整个文件.
但是看看'top'看起来我确实打开整个文件进入内存,所以我觉得我一定做错了.'顶级秀> 2.1演出'
这是一段代码片段,展示了我正在做的事情.
谢谢
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <fcntl.h>
#include <sysexits.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <cstring>
int main (int argc, char *argv[] ) {
struct stat sb;
char *p,*q;
//open filedescriptor
int fd = open (argv[1], O_RDONLY);
//initialize a stat for getting the filesize
if (fstat (fd, &sb) == -1) {
perror ("fstat");
return 1;
}
//do the actual mmap, and keep pointer to the first element
p =(char *) mmap …Run Code Online (Sandbox Code Playgroud) 如果我使用普通IO API读取和写入单个文件,则保证写入是基于每个块的原子.也就是说,如果我的write只修改了一个块,那么操作系统会保证写入整个块,或者根本不写入.
如何在内存映射文件上实现相同的效果?
内存映射文件只是字节数组,所以如果我修改字节数组,操作系统无法知道何时我认为写"完成",所以它可能(即使不太可能)在内存中交换内存我的块写操作的中间,实际上我写了半个块.
我需要某种形式的"进入/离开临界区",或"钉住"文件的页面到内存中,而我写它的一些方法.这样的事情存在吗?如果是这样,那可移植到常见的POSIX系统和Windows吗?