unix-like操作系统如何实现IPC共享内存?

时间:2010-08-26 03:59:06

标签: operating-system unix

人。我想知道unix-like操作系统如何实现共享内存?在访问系统IPC共享内存中的内存unix之间访问普通用户空间内存有什么区别?

2 个答案:

答案 0 :(得分:1)

进程内存受到保护:在程序之外,通常没有人可以访问它。这涉及“重要的”噱头:你的程序必须相信它有可用于自己的整个可寻址空间,但实际情况并非如此。据我所知,进程的地址空间被分成 pages (我认为是4k块),内核对这些页面有某种索引,它们将它们映射到物理内存或其他设备(就像你的硬盘一样,这就是你做内存映射文件的方式)。每当您的进程尝试访问内存地址时,它首先会转到该映射以查看地址实际指向的位置,然后按请求进行访问。每当进程尝试访问内核未映射到任何地方的页面时,就会出现分段错误。

因此,由于内存有些抽象,内核可以用它做各种技巧。共享内存必须是一种特殊情况,要求内核将来自不同进程的地址空间的页面映射到同一物理位置。

答案 1 :(得分:0)

实际上,正在使用的内存受到保护。当两个或多个进程具有相同的事物时,我们将其映射并分配给一个特殊的内存段。可以从两个进程访问该内存段。这是使用共享内存进行进程间通信的主要概念。

Inter process communication using shared memory下图显示了一个小的共享内存示例。 (该代码摘自John Fusco的书,《 Linux程序员的工具箱》,ISBN 0132198576,由Prentice Hall Professional于2007年3月出版,并在发布者的允许下使用。)该代码实现了父进程和子进程,该进程通过共享方式进行通信内存段。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/mman.h>
#include <sys/wait.h>

void error_and_die(const char *msg) {
  perror(msg);
  exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
  int r;

  const char *memname = "sample";
  const size_t region_size = sysconf(_SC_PAGE_SIZE);

  int fd = shm_open(memname, O_CREAT | O_TRUNC | O_RDWR, 0666);
  if (fd == -1)
    error_and_die("shm_open");

  r = ftruncate(fd, region_size);
  if (r != 0)
    error_and_die("ftruncate");

  void *ptr = mmap(0, region_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (ptr == MAP_FAILED)
    error_and_die("mmap");
  close(fd);

  pid_t pid = fork();

  if (pid == 0) {
    u_long *d = (u_long *) ptr;
    *d = 0xdbeebee;
    exit(0);
  }
  else {
    int status;
    waitpid(pid, &status, 0);
    printf("child wrote %#lx\n", *(u_long *) ptr);
  }

  r = munmap(ptr, region_size);
  if (r != 0)
    error_and_die("munmap");

  r = shm_unlink(memname);
  if (r != 0)
    error_and_die("shm_unlink");

  return 0;
}



普通用户空间和共享内存空间之间的区别在于,在IPC共享内存受保护的情况下,其他情况则不受保护。