3

我需要在 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);

但是我在“标记” 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 个链接。

4

2 回答 2

4

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

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

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

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

另见this about /proc/etc。

于 2012-02-13T18:57:44.100 回答
1

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

于 2012-02-14T05:23:11.013 回答