Shared Memory Functions
Processes and threads can communicate directly with one another by sharing parts of their memory space and then reading and writing the data stored in the shared memory. Synchronization of shared memory is the responsibility of the application program. Semaphores and mutexes provide ways to synchronize shared memory use across processes and threads.
A thread gets a shared memory identifier by calling the shmget() or shmget64() functions. Depending on the key and shmflg parameters passed in, either a new shared memory segment is created or an existing shared memory segment is accessed. The size of the shared memory segment is specified by the size parameter. When a new shared memory segment is created, the system also creates and maintains information about the shared memory segment. This information can be accessed or modified using either a basic or extended (64-Bit Enabled) data structure format. These data structures are defined in the <sys/shm.h> header file as follows:
/* Basic shared memory segment information */
typedef struct shmid_ds {
struct ipc_perm shm_perm; /* Operation permission struct*/
int shm_segsz; /* Segment size */
pid_t shm_lpid; /* Process id of last shmop */
pid_t shm_cpid; /* Process id of creator */
int shm_nattch; /* Current # attached */
time_t shm_atime; /* Last shmat time */
time_t shm_dtime; /* Last shmdt time */
time_t shm_ctime; /* Last change time */
} shmtablentry_t;
/* Extended (64-Bit Enabled) shared memory segment information*/
typedef struct shmid_ds64 {
struct ipc_perm shm_perm; /* Permissions */
pid_t shm_lpid; /* Process ID of last shared
memory operation */
pid_t shm_cpid; /* Process ID of creator */
shmatt_t shm_nattch; /* Number of current attaches*/
size64_t shm_segsz; /* Size of segment in bytes */
char shm_reserved1[4]; /* Reserved space */
time_t shm_atime; /* Time of last shmat() */
char shm_reserved2[4]; /* Reserved space */
time_t shm_dtime; /* Time of last shmdt() */
char shm_reserved3[4]; /* Reserved space */
time_t shm_ctime; /* Time of last change by
shmctl() */
psize_t shm_pagesize; /* Page size */
char shm_reserved4[24]; /* Reserved space */
} shmtablentry64_t;
A process gets addressability to the shared memory segment by attaching to it using the shmat() function. The following parameters are passed in:
- Shared memory ID
- Pointer to an address
- Flag specifying how the shared memory segment is to be attached
A process detaches a shared memory segment by calling the shmdt() function. The only parameter passed in is the shared memory segment address. The process implicitly detaches from the shared memory when the process ends.
A thread removes a shared memory ID by calling the shmctl() or shmctl64() function. The thread also can use the shmctl() and shmctl64() functions to change the data structure values associated with the shared memory ID or to retrieve the data structure values associated with the shared memory ID. The following parameters are passed in:
- Shared memory ID
- Command the thread wants to perform (remove ID, set data structure values, receive data structure values)
- Pointer to a buffer from which to set data structure values, or in which to receive data structure values.
Shared Memory Differences and Restrictions
Shared memory segments are created as teraspace-shared memory segments or as nonteraspace-shared memory segments. A teraspace shared memory segment is accessed by adding the shared memory segment to a process's teraspace. A teraspace is a space that has a much larger capacity than other i5/OS® spaces. A nonteraspace shared memory segment creates shared memory using i5/OS space objects.
A teraspace shared memory segment is created if SHM_TS_NP is specified on the shmflag parameter of shmget(), if the shmget64() function is used to create the shared memory segment, or if the program creating the shared memory segment was compiled using the TERASPACE(*YES *TSIFC) option of CRTBNDC or CRTCMOD. The following capabilities and restrictions apply for teraspace shared memory segments.
- Teraspace shared memory objects may be attached in read-only mode.
- The address specified by shmaddr is only used when
shmat() is called from a program that uses data model LLP64 and
attaches to a teraspace shared memory segment.
- After a teraspace shared memory segment is detached, it cannot be addressed
through a pointer saved by the process.
- The maximum size of a teraspace shared memory segment created via the shmget() function is 4 294 967 295 bytes (4GB minus 1 byte).
- The maximum size of a
teraspace shared memory segment created via the shmget64() function is 17 450 452 123 648 bytes (16TB minus 132GB).
- The maximum number of shared memory segments that can be created
(system-wide) is 2 147 483 646.
- A teraspace shared memory segment may be created such that its size can be
changed after it is created. The maximum size of this type of shared memory
segment is 268 435 456 bytes (256 MB).
- The page size of a
teraspace shared memory segment may be changed using the SHM_PAGESIZE
command of shmctl64() as long as it has not been attached to a process.
The i5/OS nonteraspace shared memory differs from the shared memory definition in the Single UNIX® Specification in the following ways:
- The nonteraspace shared memory segments are i5/OS space objects and can be
attached only in read/write mode, not in the read-only mode that the
Single UNIX Specification
allows. If the SHM_RDONLY flag is specified in the
shmflg parameter on a shmget() call, the call fails and
the errno variable is set to [EOPNOTSUPP].
- A nonteraspace shared memory segment can be attached only at the actual
address of the i5/OS space object, not at an address specified by the thread.
The shmaddr parameter on the shmat() function is
ignored.
- After a nonteraspace shared memory segment is detached from a process, it
still can be addressed through a pointer saved by the process. For nonteraspace
shared memory segments, i5/OS does not "map" and "unmap" regions of storage to
the address space of a process.
- The maximum size of a nonteraspace shared memory segment is
16 776 960 bytes (16 MB minus 256 bytes). Although the maximum
size of a shared memory segment is 16 776 960 bytes, shared memory
segments larger than 16 773 120 bytes (16 MB minus 4096 bytes)
should be created as teraspace shared memory segments. When the operating system
accesses a nonteraspace shared memory segment that has a size larger than
16 773 120 bytes, a performance degradation may be observed.
- The maximum number of shared memory segments that can be created
(system-wide) is 2 147 483 646.
- The size of a nonteraspace shared memory segment may be changed using the SHM_RESIZE command of shmctl() or shmctl64(), up to a maximum size of 16 773 120 bytes.
The shared memory functions are:
- shmat() (Attach Shared Memory Segment to Current Process) returns the address of the shared memory segment associated with the specified shared memory identifier.
- shmctl() (Perform Shared Memory Control Operations) provides shared memory control operations as specified by cmd on the shared memory segment specified by shmid.
- shmctl64() (Perform Shared Memory Control Operations (64-Bit Enabled)) provides shared memory control operations as specified by cmd on the shared memory segment specified by shmid.
shmctl64_time64() (Perform Shared Memory Control Operations (64-bit time64_t enabled)) allows the caller to control the shared memory segment specified by the shmid parameter.
- shmdt() (Detach Shared Memory Segment from Calling Process) detaches the shared memory segment specified by shmaddr from the calling process.
- shmget() (Get ID of Shared Memory Segment with Key) returns the shared memory ID associated with the specified shared memory key.
- shmget64() (Get ID of Shared Memory Segment with Key (64-Bit Enabled)) returns the shared memory ID associated with the specified shared memory key.
See also IPC Key Generation Functions for additional shared memory functions.