Attaching a Shared Memory Segment to an Address Space - shmat()

After a shared memory ID is returned, the next step is to attach it to the address space of a process. This is done with system call shmat(). The use of shmat() is as follows:

shm_ptr = shmat(
               int       shm_id,        /* shared memory ID    */
               char      *ptr,          /* a character pointer */
               int       flag);         /* access flag         */

System call shmat() accepts a shared memory ID, shm_id, and attaches the indicated shared memory to the program's address space. The returned value is a pointer of type (void *) to the attached shared memory. Thus, casting is usually necessary. If this call is unsuccessful, the return value is -1. Normally, the second parameter is NULL. If the flag is SHM_RDONLY, this shared memory is attached as a read-only memory; otherwise, it is readable and writable.

In the following server's program, it asks for and attaches a shared memory of four integers.

#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>
#include  <stdio.h>

int       shm_id;
key_t     mem_key;
int       *shm_ptr;

mem_key = ftok(".", 'a');
shm_id = shmget(mem_key, 4*sizeof(int), IPC_CREAT | 0666);
if (shm_id < 0) {
     printf("*** shmget error (server) ***\n");
     exit(1);
}

shm_ptr = (int *) shmat(shm_id, NULL, 0);  /* attach */
if ((int) shm_ptr == -1) {
     printf("*** shmat error (server) ***\n");
     exit(1);
}

The following is the counterpart of a client.

#include  <sys/types.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>
#include  <stdio.h>

int       shm_id;
key_t     mem_key;
int       *shm_ptr;

mem_key = ftok(".", 'a');
shm_id = shmget(mem_key, 4*sizeof(int), 0666);
if (shm_id < 0) {
     printf("*** shmget error (client) ***\n");
     exit(1);
}

shm_ptr = (int *) shmat(shm_id, NULL, 0);
if ((int) shm_ptr == -1) { /* attach */
     printf("*** shmat error (client) ***\n");
     exit(1);
}

Note that the above code assumes the server and client programs are in the current directory. In order for the client to run correctly, the server must be started first and the client can only be started after the server has successfully obtained the shared memory.

Suppose process 1 and process 2 have successfully attached the shared memory segment. This shared memory segment will be part of their address space, although the actual address could be different (i.e., the starting address of this shared memory segment in the address space of process 1 may be different from the starting address in the address space of process 2).