如何在 Linux 系统上使用 mmap() 进行读写

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9263758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:34:02  来源:igfitidea点击:

How to read and write with mmap() on a Linux system

linuxmmapsegment

提问by RobbingDaHood

I need to make some stream in and out classes using mmap() in Linux. To do so I tried to make some test code that writes some integers to a file, saves it, loads it again and write the data in the file to cout. If that test code works, then It wont be a problem making stream in and out afterwards.

我需要在 Linux 中使用 mmap() 制作一些进出类的流。为此,我尝试编写一些测试代码,将一些整数写入文件、保存、再次加载并将文件中的数据写入 cout。如果该测试代码有效,那么之后输入和输出流就不会成为问题。

When I first started out I got segment faults and If I did not get that nothing happened, so I googled a little. I found this book http://www.advancedlinuxprogramming.com/alp-folder/alp-ch05-ipc.pdfwhere around page 107 there is some usefull code. I copy pasted that code and made some small changes and got this code:

当我第一次开始时,我遇到了段错误,如果我没有得到,那就什么也没有发生,所以我用谷歌搜索了一下。我发现这本书http://www.advancedlinuxprogramming.com/alp-folder/alp-ch05-ipc.pdf在第 107 页附近有一些有用的代码。我复制粘贴了该代码并进行了一些小的更改并获得了以下代码:

int fd;
void* file_memory;

/* Prepare a file large enough to hold an unsigned integer.  */
fd = open ("mapTester", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

//Make the file big enough
lseek (fd, 4 * 10 + 1, SEEK_SET);
write (fd, "", 1);
lseek (fd, 0, SEEK_SET);

/* Create the memory mapping.  */
file_memory = mmap (0, 4 * 10, PROT_WRITE, MAP_SHARED, fd, 0);
close (fd);

/* Write a random integer to memory-mapped area.  */
sprintf((char*) file_memory, "%d\n", 22);

/* Release the memory (unnecessary because the program exits).  */
munmap (file_memory, 4 * 10);

cout << "Mark" << endl;

//Start the part where I read from the file

int integer;

/* Open the file.  */
fd = open (argv[1], O_RDWR, S_IRUSR | S_IWUSR);

/* Create the memory mapping.  */
file_memory = mmap (0, 4 * 10, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
close (fd);

/* Read the integer, print it out, and double it.  */
scanf ((char *) file_memory, "%d", &integer);
printf ("value: %d\n", integer);
sprintf ((char*) file_memory, "%d\n", 2 * integer);

/* Release the memory (unnecessary because the program exits).  */
munmap (file_memory, 4 * 10);

But I get a segment fults after the "mark" cout.

但是在“标记”cout 之后我得到了一个片段。

Then I replace the "read part" with this:

然后我用这个替换“阅读部分”:

fd = open("mapTester", O_RDONLY);

int* buffer = (int*) malloc (4*10);

read(fd, buffer, 4 * 10);

for(int i = 0; i < 1; i++)
{
    cout << buffer[i] << endl;
}

That is some working code that shows me that the file is empty. I tries out a couple of ways to write to the mapping without any change in result.

这是一些工作代码,向我显示该文件为空。我尝试了几种写入映射的方法,而结果没有任何变化。

So how am I amble to make my code write? And does my mmap read code seem okay (just in case you can see some obvious flaws)?

那么我如何才能让我的代码编写呢?我的 mmap 读取代码看起来没问题(以防万一你能看到一些明显的缺陷)?

I have found some other resources that did not help me yet, but because I am a new user I may only post max 2 links.

我发现了一些其他资源还没有帮助我,但因为我是一个新用户,我最多只能发布 2 个链接。

采纳答案by Basile Starynkevitch

You should test the result of mmap. If it gives MAP_FAILEDcheck out errnoto find out why.

您应该测试mmap的结果。如果它给出MAP_FAILED检查errno以找出原因。

And you'll better mmap a multiple of pages, often 4K bytes each, and given by sysconf(_SC_PAGESIZE)

并且您最好映射多个页面,每个页面通常为 4K 字节,并由sysconf(_SC_PAGESIZE) 给出

You can use statto find out the size of (and many other numbers about) some given file.

您可以使用stat找出某个给定文件的大小(以及许多其他数字)。

You could use straceon existing Linux programs to learn what syscalls they are doing.

您可以使用strace现有的 Linux 程序来了解它们正在做什么系统调用。

See also thisabout /proc/etc.

另请参见/proc/

回答by caf

Your scanf()call should be sscanf(), and the second open should use "mapTester"instead of argv[1]as the filename. When I fix these bugs, your posted program works (printing out 22and leaving 44in the file).

您的scanf()调用应该是sscanf(),并且第二个 open 应该使用"mapTester"而不是argv[1]作为文件名。当我修复这些错误时,您发布的程序就可以运行(打印出来22并留44在文件中)。