mmap调用的效果是原子的吗?
也就是说,对mmap访问受影响区域的其他线程而言,由 所做的映射更改是否以原子方式出现?
作为试金石,请考虑您mmap在一个全为零的文件中执行 a 的情况(来自线程T1,这是此时唯一的线程),然后开始从该区域读取的第二个线程T2。然后,再次在 T1(原始线程)上mmap对同一区域进行第二次调用,将映射替换为针对所有 1 的文件的新映射。
是否有可能为读者线程读取一些页面一(即,见第二mmap的效果),然后随后从一些页面读取零(即,见效果的第一个映射)?
您可以假设读取器线程上的读取已被正确隔离,即上述效果不仅仅由于 CPU/一致性级别的内存访问重新排序而发生。
我构建了一个应用程序,它也可以作为服务(使用-service)开关运行。当我从命令提示符运行服务时,这完全没有问题(我有一些设置可以让我在不作为真正的服务运行时从控制台调试它)。但是,当我尝试将它作为真正的服务运行,然后使用我的应用程序打开现有的内存映射时,出现错误...
找不到指定的文件。
[STAThread]
static void Main(string[] args)
{
//Convert all arguments to lower
args = Array.ConvertAll(args, e => e.ToLower());
//Create the container object for the settings to be stored
Settings.Bag = new SettingsBag();
//Check if we want to run this as a service
bool runAsService = args.Contains("-service");
//Check if debugging
bool debug = Environment.UserInteractive;
//Catch all unhandled exceptions as well
if (!debug || debug)
{
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
if (runAsService)
{
//Create service array
ServiceBase[] …Run Code Online (Sandbox Code Playgroud) 在Linux中,查看进程内存映射的最简单方法是查看/proc/PID/maps,给出如下内容:
08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm 08056000-08058000 rw-p 0000d000 03:0c 64593 /usr/sbin/gpm 08058000-0805b000 rwxp 00000000 00:00 0 40000000-40013000 r-xp 00000000 03:0c 4165 /lib/ld-2.2.4.so 40013000-40015000 rw-p 00012000 03:0c 4165 /lib/ld-2.2.4.so 4001f000-40135000 r-xp 00000000 03:0c 45494 /lib/libc-2.2.4.so 40135000-4013e000 rw-p 00115000 03:0c 45494 /lib/libc-2.2.4.so 4013e000-40142000 rw-p 00000000 00:00 0 bffff000-c0000000 rwxp 00000000 00:00 0
如何在OSX 10.5或10.6下获取有关进程自身内存映射的等效信息(地址范围,保护,映射文件名等等)?
我一直在尝试编写一些非常快速的Java代码,它必须执行大量的I/O. 我正在使用返回ByteBuffer的内存映射文件:
public static ByteBuffer byteBufferForFile(String fname){
FileChannel vectorChannel;
ByteBuffer vector;
try {
vectorChannel = new FileInputStream(fname).getChannel();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
return null;
}
try {
vector = vectorChannel.map(MapMode.READ_ONLY,0,vectorChannel.size());
} catch (IOException e) {
e.printStackTrace();
return null;
}
return vector;
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是ByteBuffer .array()方法(应返回byte []数组)不适用于只读文件.我想编写我的代码,以便它可以与内存中构造的内存缓冲区和从磁盘读取的缓冲区一起使用.但是我不想把我的所有缓冲区都包装成ByteBuffer.wrap()函数,因为我担心这会减慢速度.所以我一直在编写所有内容的两个版本,一个采用byte [],另一个采用ByteBuffer.
我应该把一切都包好吗?或者我应该双重写一切?
我理解rwxps位的含义.r-xp用于.text.rw -p用于.data/.bss/heap/stack.只是---p页面有什么用?
例如,请参阅此输出 cat /proc/self/maps
00400000-0040b000 r-xp 00000000 08:03 827490 /bin/cat 0060b000-0060c000 rw-p 0000b000 08:03 827490 /bin/cat 0060c000-0062d000 rw-p 00000000 00:00 0 [heap] 3819a00000-3819a1e000 r-xp 00000000 08:03 532487 /lib64 ld-2.11.2.so 3819c1d000-3819c1e000 r--p 0001d000 08:03 532487 /lib64/ld-2.11.2.so 3819c1e000-3819c1f000 rw-p 0001e000 08:03 532487 /lib64/ld-2.11.2.so 3819c1f000-3819c20000 rw-p 00000000 00:00 0 3819e00000-3819f70000 r-xp 00000000 08:03 532490 /lib64/libc-2.11.2.so 3819f70000-381a16f000 ---p 00170000 08:03 532490 /lib64/libc-2.11.2.so 381a16f000-381a173000 r--p 0016f000 08:03 532490 /lib64/libc-2.11.2.so 381a173000-381a174000 rw-p 00173000 08:03 532490 /lib64/libc-2.11.2.so 381a174000-381a179000 rw-p 00000000 00:00 0 7fb859c49000-7fb85fa7a000 r--p …
我有时会在某些平台上看到以下C或C++代码的语句:
int* ptr;
*ptr = 0;
Run Code Online (Sandbox Code Playgroud)
如果ptr碰巧存储该端口映射到的地址,则会导致写入硬件输入输出端口.通常它们被称为"嵌入式平台".
这些平台的真实例子是什么?
我有一些我想模仿的硬件; 我想知道我是否可以在这样的低水平做到这一点.硬件有很多寄存器,我在一个结构中排列:
#include <stdint.h>
struct MyControlStruct
{
uint32_t data_reg_1;
uint32_t data_reg_2;
uint32_t dummy[2]; // to make the following registers have certain addresses
uint32_t control_reg_1;
uint32_t control_reg_2;
};
volatile struct MyControlStruct* MyDevice = (struct MyControlStruct*)0xDeadF00;
Run Code Online (Sandbox Code Playgroud)
所以,我想在Windows和Linux上支持以下硬件访问语法:
MyDevice->data_reg_1 = 42;
MyDevice->data_reg_2 = 100;
MyDevice->control_reg_1 = 1;
Run Code Online (Sandbox Code Playgroud)
当最后一行代码执行时,我希望硬件模拟器"唤醒"并做一些事情.我可以在Windows和/或Linux上实现这个吗?我想过以某种方式捕获"分段故障"信号,但不确定这是否可以在Windows上完成,或者根本不能.
我查看了手册页mmap; 它似乎可以帮助,但我无法理解我如何使用它.
当然,我可以通过定义类似的函数来抽象对硬件的访问WriteToMyDevice,并且一切都很简单(也许),但我想了解我是否可以以这种方式安排访问我的硬件.
我可以用Java读/写一个linux块设备java.nio.以下代码有效:
Path fp = FileSystems.getDefault().getPath("/dev", "sdb");
FileChannel fc = null;
try {
fc = FileChannel.open(fp, EnumSet.of(StandardOpenOption.READ, StandardOpenOption.WRITE));
} catch (Exception e) {
System.out.println("Error opening file: " + e.getMessage());
}
ByteBuffer buf = ByteBuffer.allocate(50);
try {
if(fc != null)
fc.write(buf);
} catch (Exception e) {
System.out.println("Error writing to file: " + e.getMessage());
}
Run Code Online (Sandbox Code Playgroud)
但是,内存映射不起作用.以下代码失败:
MappedByteBuffer mbb = null;
try {
mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 100);
} catch (IOException e) {
System.out.println("Error mapping file: " + e.getMessage());
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试构建一个分布式计算系统,该系统使用内存映射文件通过VBA协调多个联网PC之间的工作.换句话说,我想让一组联网的计算机同时以协调的方式在一个项目上工作,这个项目可以很容易地分成不同的部分.一台PC需要13个多小时才能完成项目,这对我的客户来说并不实用.
我想将信息存储在内存映射文件中,以帮助PC以协调的方式处理项目(即不重复工作,避免竞争问题等).我已经尝试使用其他类型的文件来实现这一点,它会导致文件争用问题,或者它需要太长时间.所以,正如在这个论坛上所建议的那样,我正在尝试内存映射文件.
我是内存映射文件和分布式计算的新手.必须在VBA中完成.据我所知,我必须指定将文件保存在我们网络上的目录(这里是驱动器Z),所有PC都可以访问.我拼凑了来自不同地方的一些代码:
Option Explicit
Private Const PAGE_READWRITE As Long = &H4
Private Const FILE_MAP_WRITE As Long = &H2
Private Const GENERIC_READ = &H80000000
Private Const GENERIC_WRITE = &H40000000
Private Const OPEN_ALWAYS = 4
Private Const FILE_ATTRIBUTE_NORMAL = &H80
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long …Run Code Online (Sandbox Code Playgroud) 为避免复制大量数据,最好将mmap二进制文件直接处理原始数据。这种方法有几个优点,包括将分页委托给操作系统。不幸的是,我的理解是明显的实现会导致未定义行为(UB)。
我的用例如下:创建一个二进制文件,其中包含一些标识格式和提供元数据的标头(在这种情况下只是double值的数量)。文件的其余部分包含我希望处理的原始二进制值,而不必先将文件复制到本地缓冲区中(这就是我首先对文件进行内存映射的原因)。下面的程序是一个完整的(如果简单)示例(我相信所有标记为UB[X]导致 UB 的地方):
// C++ Standard Library
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <numeric>
// POSIX Library (for mmap)
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
constexpr char MAGIC[8] = {"1234567"};
struct Header {
char magic[sizeof(MAGIC)] = {'\0'};
std::uint64_t size = {0};
};
static_assert(sizeof(Header) == 16, "Header size should be 16 bytes");
static_assert(alignof(Header) == 8, "Header alignment should be 8 bytes");
void write_binary_data(const char* filename) {
Header …Run Code Online (Sandbox Code Playgroud) memory-mapping ×10
c ×2
c++ ×2
java ×2
linux ×2
memory ×2
mmap ×2
c# ×1
concurrency ×1
excel ×1
excel-vba ×1
macos ×1
permissions ×1
ports ×1
vba ×1