【问题标题】:Minimal size for mmapmmap 的最小尺寸
【发布时间】:2019-05-04 00:18:19
【问题描述】:

使用 mmap 时,共享内存的最小大小是多少?我需要创建一个内存大小足够小的程序,它最多可以读取(或保存)几个字符。我该怎么做?

将大小更改为 1、2 或 4 时,它仍会读取整个字符串。

我基于How to use shared memory with Linux in C

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

void* create_shared_memory(size_t size) {

  int protection = PROT_READ | PROT_WRITE;
  int visibility = MAP_ANONYMOUS | MAP_SHARED;

  return mmap(NULL, size, protection, visibility, 0, 0);
}

#include <string.h>
#include <unistd.h>

int main() {
  char* parent_message = "hello";  // parent process will write this message
  char* child_message = "goodbye"; // child process will then write this one

  void* shmem = create_shared_memory(128);

  memcpy(shmem, parent_message, sizeof(parent_message));

  int pid = fork();

  if (pid == 0) {
    printf("Child read: %s\n", shmem);
    memcpy(shmem, child_message, sizeof(child_message));
    printf("Child wrote: %s\n", shmem);

  } else {
    printf("Parent read: %s\n", shmem);
    sleep(1);
    printf("After 1s, parent read: %s\n", shmem);
  }
}

【问题讨论】:

  • sizeof parent_messagesizeof(char*)。并且 mmap() 在内存页面(主要是 4096 字节)中计数,因此您的大小(4 或 8)会向上取整,(但在读取/写入实际磁盘文件时会丢弃尾部)
  • 如果您希望sizeof 按预期工作,请使用const char parent_message[] = "hello";。它将包括终止 NULL 字符。这同样适用于child_message。在这种情况下,我认为最好使用在指针上失败的COUNTOF 宏。类似Array-size macro that rejects pointers
  • 这些看起来也有问题:printf("Child read: %s\n", shmem);(和朋友)。我看不到您用NULL 终止复制的字符串的位置。

标签: c linux unix memory mmap


【解决方案1】:

为您收到的内存段保留的实际大小取决于操作系统。通常,在全页面虚拟内存系统上,系统以页面为单位为进程分配内存,这意味着,对于您的情况,将分配最小页面大小(在 32/64 位 linux 中为 4Kbytes)

对于小块内存,使用的是调用malloc(3) 和它的朋友,因为这可以为您处理最小化系统调用次数和小于通常应用程序请求的页面块的内务。通常是malloc(3) 调用sbrk(2)memmap(2) 来处理这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-12
    • 2016-10-27
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    • 2019-02-21
    相关资源
    最近更新 更多