Using Shared Memory in Linux Programming

Shared memory is one way for processes to share information with each other. In the Linux environment, there are two main ways of obtaining shared memory in C or C++. The first method uses shmget to obtain an ID for the shared memory segment, then using shmat to attach the segment to the address space of the calling process. The declaration of these methods are as follows:

int shmget(key_t key, size_t size, int shmflg);

void *shmat(int shmid, const void *shmaddr, int shmflg);

The parameter key identifies the shared memory segment. Two different processes should use the same key to obtain the same segment. The key could be some defined int. However, another application might be using the same key value to obtain shared memory.

Another way of obtaining the key is to use ftok. ftok generates a key value based on a file and will return the same key value when given the same file. shmget will create the shared memory segment if needed. The parameter shmflg parameter determines which permissions are assigned to the segment and how they get created. The permissions are specified in the same way as they are specified for open. See the documentation for shmget for more information about the paramter. An example of obtaining the shared memory, without checking for errors:

    const char *keyFile = "/tmp/key.dat";
    /* Make sure the file exists. */
    int descriptor = open(keyFile, O_CREAT | O_RDWR, S_IRWXU);

    /* Only wanted to make sure that the file exists. */
    close(descriptor);

    /* Generate memory key. */
    key_t sharedKey = ftok(keyFile, 1);

    /* Get the shared memory segment id. Note we include
       the permissions. */
    int sharedSpaceId = shmget(sharedKey, sizeof(int), 
        IPC_CREAT | S_IRUSR | S_IWUSR);

    /* Attach the shared memory segment. */
    int *result = (int *) shmat(sharedSpaceId, NULL, 0);

After calling shmat, result will either be -1 (this indicates an error) or pointing to the shared memory segment. If it is pointing to the shared memory segment, you can use result just like any other pointer. Since the write permission was assigned to the shared segment (at line 14), another process can attach to the same segment and read and write to it.

A second process utilitising the same could be able to access the same memory space with the same code fragment. When the process no longer needs the reference to the shared memory segment, it should detach from it. This is done by calling shmdt on the pointer. To delete the shared memory segment, use shmctl. Following from the above example, detaching and destroying the created and attachment segment:

    struct shmid_ds shmid;
    shmctl(sharedSpaceId, IPC_RMID, &shmid)
    shmdt(result);

Another way of using of using shared memory is via shm_open and mmap. While shmget uses the Linux interprocess communication (IPC) facilities and creates shared memory segments in memory, shmopen creates a shared memory object based on a file. After creating the shared memory object, mmap is called to map to shared region of memory. The declarations for these methods:

int shm_open(const char *name, int oflag, mode_t mode); 

void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); 

The parameter mode specificies the permissions of the shared memory. Without the appropriate permissions set, another process will not be able to access the shared memory object. An example of obtaining shared memory using shm_open, without any of the error checking:

    int *result = NULL;
    int integerSize = sizeof(int);

    /* Open the shared memory. */
    int descriptor = shm_open(SHM_FILE, 
        O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);

    /* Size up the shared memory. */
    ftruncate(descriptor, integerSize);
    result = mmap(NULL, integerSize, 
        PROT_WRITE | PROT_READ, MAP_SHARED, 
        descriptor, 0 );

The call to ftruncate (at line 9) sets the size of the object. When it is initially created, it is initially allocated 0 bytes. After the call to mmap, the pointer result is pointing to the shared memory region. The process can now share an integer by placing it at the location at the pointer.

After finishing with the shared memory, it should be “unmapped” with munmap and “unlinked” with shm_unlink. Following from the above example:

    munmap(result, sizeof(int));
    shm_unlink(SHM_FILE);
About these ads

9 Responses to Using Shared Memory in Linux Programming

  1. icegood says:

    What mean variable “status” in munmap call?

    • kahgoh says:

      I must have made a typing mistake. The status is supposed to be the mapped area returned by mmap (i.e. the result pointer). I’ve corrected it now.

  2. Pingback: Child processes

  3. pranjal says:

    hi how did you attach the code on this page. Is there a plugin in wordpress. Tell me i too want to put code on my wordpress page.

  4. Mamie says:

    Hey this is kind of of off topic but I was wanting to know if blogs use WYSIWYG editors or if you have to manually code with HTML.

    I’m starting a blog soon but have no coding knowledge so I wanted to get advice from someone with experience. Any help would be greatly appreciated!

  5. e271p314 says:

    A small typo
    When the process needs to reference the shared memory segment, it should detach from it
    =>
    When the process doesn’t need to reference the shared memory segment any longer, it should detach from it

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: