- Shared memory is the fastest and most efficient means of inter-process communication.
- It allows two or more processes to access the same memory as if both the processes called malloc and were returned pointer to the same memory address.
- The scope of this inter-process communication is local, that is within a single system(intra host).
- Since all the processes share the same address space, it needs an exclusive synchronization to avoid any race conditions.
- This is considered to be the fastest because data does not need to be copied among processes.
- The memory which is shared is not from process’s own address space, rather it is from the system-free pool of memory. Later this is attached to process address space.

/* Creating a shared memory */ int shmget (key_t key, size_t size, int flags); /* Attaching the shared memory */ void *shmat(int shmid, const void *shmaddr, int flag); /* Detaching the shared memory */ void *shdt(const void *shmaddr); /* Controlling the shared memory segment */ int shmctl (int shmid, int cmd, struct shmid_ds *buf);
- The shared memory is created by shmget() system calls.
- Syntax: int shm_id = shmget (key_t key, size_t size, int flags);
- The first parameter(key) is a kind of name to the shared memory which can be used by other processes to access the same memory segment.
- The second parameter(size) specifies the size of the segment in a number of bytes, actual bytes rounded up to multiple of the page size.
- The third parameter(flags) specifies access permissions flags and creation control flags.
- Few common flags are:
- IPC_CREAT : If a segment for the key does not exist, it is created else return the existing
- IPC_CREAT | IPC_EXCL : This is for creating a new memory segment if the segment exists with the given key, it fails.
- Permission flag to indicate permission granted to the owner, group, and all other processes.
- It returns -1 on failure and shared memory id in case of success.
key_t key =121; /* If the key exist, it fails */ int shm_id = shmget(key, 10, 0666 | IPC_CREAT | IPC_EXCL); if (shm_id == -1) { printf("\n Failure in creating a shared memory %d %s\n",errno, strerror(errno)); exit(EXIT_FAILURE); }
- The shared memory created is not on the process private address space, rather it’s from the system pool of free memory.
- Thus this must be attached to process own address space.
- This is done with shmat() system calls.
- Syntax: void * shmat( int shm_id, const void *shm_add, int flags);
- The first parameter(shm_id) is the shared memory identifier, return value of shmget().
- The second parameter specifies the address when the created shared memory can be attached or mapped. In most cases this is NULL, it is left to system to choose the address.in
- The third parameter is the flag: SHM_RND and SHM_RDONLY
- SHM_RND : This specifies that the address specified should be rounded down t to multiple of page size
- SHM_RDONLY : This indicates that this segment is read-only, not written.
- This return -1 in case of failure or pointer to first byte of the memory segment.
char *addr; /* Attaching it address space */ if ((addr = shmat(shm_id, NULL, 0)) == (char *)-1) { printf("\n Attaching memory failed %d %s\n", errno, strerror(errno)); exit(EXIT_FAILURE); } printf("\n Successful attachment at address %x\n", addr);
- The shared memory segment can be detached from process address space by calling shmdt() system call.
- Syntax: shmdt (const void * shmaddr);
- The parameter passed is the address of the memory segment to be detached( return address of shmat()).
It return 0 on success and -1 on failure. /* Detaching it address space */ if (shmdt(addr)== -1) { printf("\n Detaching memory failed %d %s\n", errno, strerror(errno)); exit(EXIT_FAILURE); }
- This is for control operations of a shared memory segment identified by the shmid.
- Syntax: int shmctl (int shm_id, int cmd, shmid_ds *buffer);
- The first parameter is the shared memory id.
- The second parameter specifies the command, some of the common commands are:
- IPC_RMID: Remove the shared memory segment.
- IPC_SET: We can set some fields in the shmid_ds structure in the kernel.
- IPC_STAT: It copies the data in the kernel data structure(shmid_ds) into the location pointed by the buffer.
- The third parameter is the pointer to buffer where data in the kernel structure shmid_ds is placed. It is used with command IPC_STAT and IPC_SET.
- It returns 0 on success and -1 on failure.
Note:
- IPC_RMID mark the segment to be destroyed. The segment will only actually be destroyed after the last process detaches it (i.e., when the shm_nattch member of the associated structure shmid_ds is zero).
- Command in Linux is : ipcs –help
#include <stdio.h> #include <sys/shm.h> #include <stdlib.h> #include <errno.h> #include <string.h> int main() { key_t key = 20; void *ptr; struct shmid_ds shmid_ds, *buffer; buffer =&shmid_ds; /* Creating the shared memory */ int shm_id = shmget(key, 10, 0666 | IPC_CREAT ); if (shm_id ==-1) { printf("\n Failure in creating a shared memory %d %s\n",errno, strerror(errno)); exit(EXIT_FAILURE); } else { printf("\n Shared memory creation successful id: %d\n",shm_id); } /* Attaching the shared memory to address space */ if((ptr = shmat(shm_id, NULL, 0))== (char *)-1) { printf("\n Shared memory failed to attach \n"); exit(EXIT_FAILURE); } else { printf("\n Successful attach at address %x\n", ptr); } /* Fetching the shared memory details */ int ret = shmctl(shm_id, IPC_STAT, buffer); if ( ret == -1) { printf("\n Fetching the shared memory info failed %d %s\n",errno, strerror(errno)); exit(EXIT_FAILURE); } else { printf("\n Fetching the shared memory info success\n"); printf("\n size is: %d no of process attach is: %d\n", buffer->shm_segsz, buffer->shm_nattch); } /* Deleting the shared memory */ ret = shmctl(shm_id, IPC_RMID, buffer); if ( ret == -1) { printf("\n Deleting the shared memory ailed %d %s\n",errno, strerror(errno)); exit(EXIT_FAILURE); } else { printf("\n Deleting the shared memory success\n"); } return 0; }
Output:
[aprakash@wtl-lview-6 shared_memory]$ gcc cntl_shm.c [aprakash@wtl-lview-6 shared_memory]$ ./a.out Shared memory creation successful id: 346488849 Successful attach at address 87c89000 Fetching the shared memory info success size is: 10 no of process attach is: 1 Deleting the shared memory success
Data structure
struct shmid_ds { struct ipc_perm shm_perm; /* Ownership and permissions */ size_t shm_segsz; /* Size of segment in bytes */ time_t shm_atime; /* last attach time */ time_t shm_dtime ; /* last detach time */ time_t shm_ctime; /* last change time */ pid_t shm_cpid; /* Pid of creator */ pid_t shm_lpid; /* Pid of last shmat or shmdt */ shmatt_t shm_nmatch /* No of current matches */ } Where. the struct ipc_perm is, struct ipc_perm { key_t __key; /* Key supplied to shmget(2) */ uid_t uid; /* Effective UID of owner */ gid_t gid; /* Effective GID of owner */ uid_t cuid; /* Effective UID of creator */ gid_t cgid; /* Effective GID of creator */ unsigned short mode; /* Permissions + SHM_DEST and SHM_LOCKED flags */ unsigned short __seq; /* Sequence number */ }; The fields that can be modified are shm_perm.uid, shm_perm.gid and the least significant 9 bits of shm_perm.mode.
Relevant Posts:
- Introduction to Inter-process communication
- Message Queue
- Pipes
- Signals
‹ Signals
Categories: Operating system (OS)
Leave a Reply