Feb 22, 2012

shared memory in C

A shared memory is nothing but a piece of memory shared across multiple process.

These are the four important functions associated with shared memory defined in sys/shm.h.
  1. void *shmat(int shm_id, const void *shm_addr, int shmflg);
  2. int shmctl(int shm_id, int cmd, struct shmid_ds *buf);
  3. int shmdt(const void *shm_addr);
  4. int shmget(key_t key, size_t size, int shmflg); 
So these are two programs.
------------------------------------------------------------------------------------
//first.c 
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>
int main ( void ) {
        int shmid;
        void *shared_memory = (void *) 0;
        shmid = shmget ( (key_t)1234 , 32 , 0666 | IPC_CREAT );
        if ( shmid == -1 ) {
                printf ( "shmget failed!\n" );
        }
        shared_memory = shmat ( shmid, (void *)0, 0 );
        if ( shared_memory == ( void *)-1 ) {
                printf ("shmat failed!\n");
        }
        memset ( shared_memory, '\0', 32 );
        while ( memcmp ( shared_memory, "\0\0\0\0\0", 3 ) == 0);     
        printf ("yoyo\n");

        if ( shmdt ( shared_memory ) == -1 ) {
                printf ("shmdt failed!\n");
        }
        if ( shmctl ( shmid, IPC_RMID, 0 ) == -1 ) {
                printf ( "IPC_RMID failed!" );
        }
        return 0;
} 
------------------------------------------------------------------------------------
//second.c
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>
int main ( void ) {
        int shmid;
        void *shared_memory = (void *) 0;
        shmid = shmget ( (key_t)1234 , 32 , 0666 | IPC_CREAT );
        if ( shmid == -1 ) {
                printf ( "shmget failed!\n" );
        }
        shared_memory = shmat ( shmid, (void *)0, 0 );
        if ( shared_memory == ( void *)-1 ) {
                printf ("shmat failed!\n");
        }
        memset ( shared_memory, '\0', 32 );
        memset ( shared_memory, 'c', 32 );
        if ( shmdt ( shared_memory ) == -1 ) {
                printf ("shmdt failed!\n");
        }
        if ( shmctl ( shmid, IPC_RMID, 0 ) == -1 ) {
                printf ( "IPC_RMID failed!" );
        }
        return 0;
}
------------------------------------------------------------------------------------
Put that include files inside < and >  (blogger takes it as html code, so I removed that)
compile them:
gcc -o first first.c
gcc -o second second.c

run ./first in a terminal 
open another terminal and run ./second

first will be in wait until second runs.

Explanation : 
Actually first program creates a shared memory with key 1234. The same key is used by second program to get access to the shared memory. First program will write null ('\0') to the full 32 bytes of shared memory and will wait (while ( memcmp ( shared_memory, "\0\0\0\0\0", 3 ) == 0);) until there is a change to that bytes. When the second program writes some characters into the shared memory, first comes out of the loop and terminates. But the first program prints 'IPC_RMID failed', why ? ;).
-------------------------------------------------------------------------------------
Reference:
Beginning Linux Programming (Book): http://cadcg.hfut.edu.cn/teach/Beginning.Linux.Programming,4th.pdf

For Web Developer

  open -a "Google Chrome" --args --disable-web-security