Document Sample
C++ Powered By Docstoc
					Shared Memory
  Shared Memory is a very common IPC mechanism – it has one distinct
    advantage over message queues
       If two (or more) processes need to shared information – they do not need
        to copy the information into a message and pass it – they right it to
        memory and everyone reads it – no copying !!
       However, with this flexibility comes some drawbacks
  As discussed in OSF, shared memory is the ability to mark a block of
    memory as no longer being private and totally owned by one process
       Within a UNIX process, memory is a private resource – if one process tries
        to access another processes memory, a protection fault will be raised
       Shared memory is the ability (through the kernel) to register a block of
        memory as being a resource common to two (or more) processes – to avoid
        the protection faults
  In UNIX, the API provided to allocate, deallocate, access and share an
    area of memory if pretty much the same as what we saw last week with
    Message Queues

Lesson 08 - Shared Memory
Creating and Destroying
  Shared Memory is a resource that you must allocate – it
    does not automatically exist
       As we saw with queues, we first need to create a common public
         identifier – that the multiple process es may use to gain access to
         the shared memory block.
  There is one thing to note that you must think about while
    reviewing this information
       Although multiple processes can access an area of shared memory
         (in a client / server architecture) – dangerous situations can arise if
         two processes physically alter data within the memory at the same
            Need to manage resource using critical region processing

Lesson 08 - Shared Memory
             #include <sys/types.h>
             #include <sys/ipc.h>

             key_t ftok(char* path, int id);

       This function returns a special data-type called a key type
            This value will be used throughout the rest of the client or server in gaining access
             to the shared memory
       if the system is unable to determine and generate a key-type value
         for the shared memory, then the function returns an the standard
         error (-1)
            You can use errno to check the real reason for the failure

Lesson 08 - Shared Memory
             #include <sys/types.h>
             #include <sys/ipc.h>
             #include <sys/shm.h>

             int shmget(key_t key, int memSize, int memFlag);

       This function is called to check for the existence of shared memory
         as specified by the 1st parameter
            If the system cannot locate such a block of memory, then an error is returned (-1)
            If the system finds the memory, then the return value is the shared memory ID
       The 2nd parameter is the number of bytes of space this memory
        should be
       The 3rd parameter indicates how you would like to obtain the
        shared memory
            If the value is zero (0) – then check for the existence of the memory
            If you pass in the constant IPC_CREAT or’d with some permission bits, it means
             you are trying to create a block of memory with those permissions
                 Remember that the purpose of this memory is to allow different processes to read and write from it , best
                  permission to turn on would be the octal value 0660 (equivalent to rwxrwx---)

Lesson 08 - Shared Memory
shmget() - Example

         key_t              shmKey;   //   memory’s key-type value
         int                shmID;    //   memory’s ID

         if((shmID = shmget(shmKey,1000,0)) == -1)
            // memory doesn’t exist – create it
            shmID = shmGet(shmKey, 1000, (IPC_CREAT | 0660));
            if(shmID == -1)
                  // error

Lesson 08 - Shared Memory
How does this work?
  If the server is started first and creates / allocates the
    memory, then the 1st call to shmget() in the client will
    return the existing memory ID

  If the memory hasn’t been allocated, then either the server
    isn’t running or something serious has happened to
    deallocate the memory
       If the server isn’t running, then the client can perform a fork() /
        exec() set of commands to launch the server and allow it to run
        simultaneously with itself (the client)
       Or if this is not the chosen application architecture, the client can
        sleep() and check again later or do something else (like report the
        issue and exit)

Lesson 08 - Shared Memory
             #include <sys/types.h>
             #include <sys/ipc.h>
             #include <sys/shm.h>

      int shmctl(int shmID, int cmd, struct shmid_ds *buf);

       This function is called among other things – to deallocate the
         shared memory when all processing is complete
         In this case, the final parameter is left as a NULL
         And the constant IPC_RMID is sent as the command

      retCode = shmctl(shmID, IPC_RMID, (struct shmid_ds *)NULL);

       You can view the IPC resources using the “ipcs” system command
            If you know the shmID value of the shared memory – you can remove it through
             the system command “ipcrm –m <shmID Value>”

Lesson 08 - Shared Memory
Using / Accessing Shared Memory
  Once the memory has been allocated, you are now ready to begin using
  UNIX does not dictate what can and cannot be done with this shared
       Often times one application acts as the producer of the information while other
        applications attached to the shared memory act as the consumers
       For example, process #1 allocates a 10K buffer for use in storing values for sensor
        reading that it is taking.
            This memory could be organized as a circular buffer – so that the one program will produce and populate the
             data as the sensor readings are made
            And secondary programs will read from the buffer when needed and report on the data – thus secondary
             programs consume the data
       This approach to data management is more efficient that message passing – you
         don’t have to copy huge blocks of data into a queue while other applications don’t
         have to copy to read it
  Another common data structure used with shared memory is the data
       This queue is software controlled – unlike the message queue which is O/S
       The data queue object has a head and tail member – allowing new information to
        written to the head and other applications to read from the tail

Lesson 08 - Shared Memory
             #include <sys/types.h>
             #include <sys/ipc.h>
             #include <sys/shm.h>

      void* shmat(int shmID, const void* shmAddr, int shmFlag);

       This function is called get the address of the shared memory block
            The 1st parameter is the shared memory ID
            The 2nd parameter is generally left as NULL, but if you want the shared memory to
             be found at a specific memory location then you provide it here
            The 3rd parameter is generally left as zero – through this f lag you can attach to
             shared memory with read-only permissions if you like
       As always – if the attach fails the return code from the function call
         will be -1 (and errno can be checked for details)

Lesson 08 - Shared Memory
             #include <sys/types.h>
             #include <sys/ipc.h>
             #include <sys/shm.h>

                            int shmdt(void* memAddr);

       This function is called to release access (detach) to a shared
         memory block
            The 1st parameter is the shared memory address that was returned to you by shmat()
       As always – if the send fails the return code from the function call
         will be -1 (and errno can be checked for details)

Lesson 08 - Shared Memory
Problems with Shared Memory
  As mentioned earlier – although shared memory is a far more efficient
    way of moving large volumes of data between programs, problems can
    arise when 2 or more programs attempt to alter the memory contents
    (i.e. two memory writers)
         Consider the producer and niceConsumerapplications
             The producer is generating the next coin toss and storing it in the pos position of the circular
             Since the consumer is also using this pos position value to get the current toss, what would
              happen if the consumer managed to change the value of the pos member (or worse yet –
              corrupt it)?
             Since the producer simply uses the shared memory directly, if the consumer corrupted this
              pos value, the producer might produce erroneous results – or worse yet - CRASH
       Data Queues are worse still – if 2 applications write to a data queue, we can
          run into the classic example of a producer / consumer processing
             FACT: it takes finite amount of time to manipulate the head/tail members of the
              data queue
             What happens if task #1 is suspended by the O/S in the midst of adjusting the
              head of the queue ?
             What if task #2 which is now running also tries to write to the head of the queue –
              the partial write from task #1 will be corrupted by the write of task #2

Lesson 08 - Shared Memory