How do unix-like OS implement IPC shared memory?
guys. I am wondering how do unix-like OS implement shared memory? What is difference between accessing a normal user-space memory between accessing a memory unix in sytem IPC shared m开发者_JS百科emory?
Process memory is protected: outside of your program, normally no one can access it. This involves "important" gimmicks: your program has to believe it has the whole addressable space usable for himself, which is not the case. As I understand it, the address space of a process is split into pages (4k blocks I think), and the kernel has some sort of index for those pages, which maps them to physical memory or other devices (like your hard drive, that's how you do memory-mapped files). Whenever your process tries to access a memory address, it first goes to that map to see where the address actually points, and then does the accesses as requested. And whenever the process tries to access a page the kernel hasn't mapped anywhere, you get a segmentation fault.
So since memory is somewhat abstracted away, the kernel can do all kinds of tricks with it. Shared memory gotta be a sort of special case, where the kernel is asked to map pages from different processes' address space to the same physical location.
Actually a memory using in process are protected. When two or more process have same thing then we map it and give it to a special memory segment. That memory segment can be access able from both process. That is the main concept of inter process communication using shared memory.
Inter process communication using shared memoryBelow shows a small shared memory example. (The code is derived from John Fusco's book, The Linux Programmer's Toolbox, ISBN 0132198576, published by Prentice Hall Professional, March 2007, and used with the permission of the publisher.) The code implements a parent and child process that communicates via a shared memory segment.
#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;
}
The difference between normal user space and shared memory space is that in the case of IPC shared memory is protected but other case is not.
精彩评论