【问题标题】:How to read and write with mmap() on a Linux system如何在 Linux 系统上使用 mmap() 进行读写
【发布时间】:2012-03-05 01:06:14
【问题描述】:

我需要在 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 之后得到了一个片段。

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

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 个链接。

【问题讨论】:

    标签: linux mmap segment


    【解决方案1】:

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

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

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

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

    另请参阅this 关于/proc/ 等。

    【讨论】:

    • 谢谢你的帮助,我发现我写的文件写保护,因此一切都失败了。
    【解决方案2】:

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

    【讨论】:

    • 我无法让代码与您所说的更改一起工作。我不知道如何在评论中格式化代码,所以我只是把它放在消息的末尾。我用的是g++编译器命令,你用的是别的吧?
    • 好的,我不能添加更多代码,因为它太长了。我复制了我在这里编写的代码并更改了 2 个位置,它在代码的最后部分出现了分段错误。但是感谢您的 2 个好建议,非常有帮助:)
    猜你喜欢
    • 2017-11-14
    • 1970-01-01
    • 2015-01-01
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    相关资源
    最近更新 更多