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

发布于 2025-01-04 17:40:11 字数 1988 浏览 2 评论 0原文

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

当我第一次开始时,我遇到了段错误,如果我没有意识到什么也没有发生,所以我用谷歌搜索了一下。我找到了这本书 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);

但是我在“mark”cout 之后得到了一个段 fults。

然后我将“读取部分”替换为:

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;
}

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

那么我该如何编写我的代码呢? 我的 mmap 读取代码看起来还可以吗(以防万一您可以看到一些明显的缺陷)?

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

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.

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.pdf where around page 107 there is some usefull code. I copy pasted that code and made some small changes and got this code:

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.

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)?

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鹊巢 2025-01-11 17:40:11

您应该测试 mmap 的结果。如果出现 MAP_FAILED,请查看 errno 以找出原因。

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

你可以使用 stat 来找出(以及许多其他数字关于)一些给定的文件。

您可以在现有的 Linux 程序上使用 strace 来了解它们正在执行哪些系统调用。

另请参阅关于 /proc/ 等的

You should test the result of mmap. If it gives MAP_FAILED check out errno to find out why.

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

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

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

See also this about /proc/ etc.

懒猫 2025-01-11 17:40:11

您的 scanf() 调用应为 sscanf(),第二次打开应使用 "mapTester" 而不是 argv[1] 作为文件名。当我修复这些错误时,您发布的程序可以正常工作(打印出 22 并将 44 保留在文件中)。

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 22 and leaving 44 in the file).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文