Shared Memory By Oren Kalinsky 1
Overview Shared memory (SHM) - two or more processes can share a given region of memory A form of Inter Process Communication (IPC) Other IPC methods pipes, message queues SHM is the fastest method avoids kernel! Shared needs synchronization (Semaphores)
Shared Memory The virtual memory pages of each process points (mapped) to the same physical address of the shared memory pages Virtual Physical 3
Unix Shared Memory Unix supports multiple shared memory APIs: Shared mappings by using mmap Anonymous between related processes (fork) File between unrelated processes (file on the disk) POSIX shared memory Between unrelated processes No I/O overhead 4
POSIX Shared Memory Implementation map (mmap) files in a dedicated tmpfs (/dev/shm/) filesystem tmpfs virtual memory filesystem (in memory) Employs swap space when needed Objects have kernel persistency Exists until explicitly deleted or system reboots It is possible to map an object, change it and unmap 5
POSIX shared memory APIs shm_open() open an existing or create a new SHM object ftruncate() set the size of SHM object mmap() map SHM object into caller s address space 6
POSIX shared memory APIs munmap() unmap a mapped SHM object from caller s address space close() close the fd returned by shm_open() shm_unlink mark SHM object for deletion(once all processed have closed) fstat() get stat structure of fd(size, ownership, permissions ) 7
Creating/opening a SHM Creates a new object or opens an existing Parameters - name name of SHM ( shareme ) oflag flags (create, rdonly, rdwr, ) mode permission bits RWX for User, group or other If existing object, set as 0 8
Shared Memory size New SHM objects have length 0 Before mapping, set size ftruncate(fd, size) How to get size of existing object? fstat() 9
Mapping a shared memory mmap set memory mapping in caller s virtual address space Parameters: addr suggest a virtual address for object Normally, use NULL to let system choose length size of mapping (will be rounded up to multiple of page size) prot memory protections (RD, WR, ) flags use MAP_SHARED for POSIX shared memory fd fd returned by shm_open Offset offset of mapped underlying file Returns the mapped virtual address of the SHM 10
Example: Create SHM 11
Example Write SHM 12
Example Read SHM 13
Storing Pointers in SHM Warning - mmap() can map SHM objects at arbitrary locations in memory Example: a pointer is stored in SHM Where it points if SHM is mapped to a different location in another process? Absolute addresses has no meaning Use relative offsets, not absolute addresses 14
Storing Pointers in SHM Example: baseaddr = mmap( ) Store pointer to target in *p Wrong way: *p = target; Correct way: *p = target baseaddr; Dereference: target = baseaddr + *p; 15
POSIX SHM New APIs shmget - get a SHM id (new or existing) shmat - attach to an existing SHM shmdt detach from and existing SHM shmctl perform operations on a SHM 16
shmget #include<sys/types.h> #include<sys/ipc.h> #include<sys/shm.h> int shmget(key_t key, int size, int flag); get a SHM id (new or existing) Params: key system wide SHM identifier ( IPC_PRIVATE for new allocation by the kernel) Size the size of the SHM in bytes Flag permissions and creation control flags Returns an SHM id, or -1 on error 17
shmat\shmdt #include<sys/types.h> #include<sys/ipc.h> #include<sys/shm.h> void* shmat(int shmid, const void* addr, int flag); void* shmdt(const void* addr); Attach an existing SHM identified by shmid Params: shmid SHM id addr suggested virtual address for SHM Flag permissions Returns a pointer to SHM segment, or -1 on error Example: char* buf = (char*)shmat(shmid,0,0); 18
shmctl #include<sys/ipc.h> #include<sys/shm.h> int shmctl(int shmid, int cmd, struct shmid_ds *buf); Perform control operation specified by cmd on the shared memory segment whose identifier is given in shmid Params: shmid SHM id cmd command (IPC_STAT, IPC_SET, IPC_RMID, ) buf status buffer (permissions, uid, gid, key, ) Returns 0 on success, or -1 on error 19
SHM example Create a server and client programs that use a shared memory to pass a message between them. Message is all the letters from a to z The server will wait until the client received the message 20
SHM example - server void main() { char c; int shmid; key_t key; char *shm, *s; key = 5678; // name our shared memory segment 5678 if ((shmid = shmget(key, 27/*size*/, IPC_CREAT 0666/*flags*/)) < 0) { // Create the segment perror("shmget"); exit(1); } if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { // attach the segment to our data space perror("shmat"); exit(1); } // put some things into the memory for the other process to read. s = shm; for (c = 'a'; c <= 'z'; c++) *s++ = c; *s = NULL; // wait until the other process changes the first character of our memory to '*' while (*shm!= '*') sleep(1); } 21
SHM example - client void main() { int shmid; key_t key; char *shm, *s; key = 5678; // get the segment named 5678 if ((shmid = shmget(key, 27/*size*/, 0666/*flags*/)) < 0) { perror("shmget"); exit(1); } // attach the segment to our data space if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { perror("shmat"); exit(1); } // read what the server put in the memory for (s = shm; *s!= NULL; s++) putchar(*s); putchar( \n ); // change the first character of the segment to '*' *shm = '*'; } What are the problems? How could we better handle the synchronization between the two processes? Semaphores!!! 22
Summary Share Memory is a form of IPC There are two common SHM mechanisms: File based Memory based (POSIX) Pointers in shared memory save offsets! There are two equivalent POSIX SHM APIs, which implement - create\get, attach and detach operations The new API is more common (no need for truncate to allocate shared memory size) 23