Docstoc

IPC

Document Sample
IPC Powered By Docstoc
					                                                   Operating Systems
                      Interprocess Communication (IPC)
Brian Bramer (thanks to Steve Rumsby for original notes)

Most modern operating systems are multi-tasking (e.g. Unix, O/S2, Linux, Windows Nt, Windows 95,...). Also with the
increase in LANs the processes could be on different CPU's.

Often processes want to communicate. We can split them into two types :-

         Uniprocessor IPC                         multiprocessor IPC
                                                  /                \
                                           Distributed systems     Multi-CPU systems
                                              (Networked)            (Shared bus)

We won't be looking at the Multi-CPU IPC.
Most mechanisms are provided by the O/S, but some are language dependent (e.g. StartProcess, etc. in Modula-2).
Usually processes form a client/server or consumer/producer relationship.


1 Producer/Consumer relationship. ....................................................................................................................... 2
2 Peer to Peer model and client/server model ........................................................................................................ 2
3 Overview of I.P.C. Mechanisms ......................................................................................................................... 3
  3.1 Shared memory. ............................................................................................................................................ 3
  3.2 Message passing. ......................................................................................................................................... 3
  3.3 Remote Procedure Call (RPC). .................................................................................................................... 3
4 Shared Memory .................................................................................................................................................. 4
  4.1 Access control - TAS instruction ................................................................................................................. 4
  4.2 Acess control - Sleep and Wakeup ............................................................................................................. 5
  4.3 Access control - Semaphores ....................................................................................................................... 5
  4.4 Access control - event counters ................................................................................................................... 6
5 UNIX IPC ........................................................................................................................................................... 7
  5.1 Pipes ............................................................................................................................................................. 7
  5.1.1 Non-blocking Read and Writes on Pipes ................................................................................................... 8
  5.2 Named pipes ................................................................................................................................................ 9
  5.3 Record Locking ......................................................................................................................................... 11
6 Berkeley UNIX ................................................................................................................................................. 12
7 System V UNIX ................................................................................................................................................ 12
  7.1 Message Passing ........................................................................................................................................ 12
  7.3 Semaphores ................................................................................................................................................ 13
  7.4 Shared Memory ......................................................................................................................................... 15
  7.5 Message Passing ........................................................................................................................................ 15




Unix Operating System: Interprocess Communication (IPC)                                                                                                       1
 1 Producer/Consumer relationship.
Typically one process generates data, the other receives it, i.e. producer/consumer

They need to synchronise, e.g. we have a loop where
   1. Producer generates some data
   2. Consumer reads the data

Note:
                 Consumer needs to know when data has been produced.
                 Producer needs to know when it can produce more data.
i.e. there has to be a handshaking convention, i.e. similar effect happens in hardware with I/O devices.


Producer/Consumer process is
     Producer               Buffer           Consumer
     Need a variable – freeslots –indicates if anything is in buffer


Producer algorithm:
       loop
                if freeslots > 0 then
                          add an item
                          decrease freeslots by 1
       endloop

Consumer algorithm
      loop
              if freeslots < BUFSIZE then
                        remove an item
                        increase freeslots by 1
         endloop


2 Peer to Peer model and client/server model
Peer to peer

         Process A                   Process B
         send message               rec message
         rec message                send message

Client/Server

         Client                            Server
                                         loop
         send message                     wait for message
         rec message                     send message
                                         end loop

Note server runs continuously in a loop. Client runs then finishes.

UNIX servers called daemons, e.g.
           o Clients telnet, ftp …
           o Sever daemons are telnetd, ftpd, …

Unix Operating System: Interprocess Communication (IPC)                                                    2
    Deadlock

Deadlock can occur when 2 (or more) threads of control are competing for resources.

Definition: A set of threads is deadlocked if each thread in the set is waiting for an event that only another thread in the
set can cause.




3 Overview of I.P.C. Mechanisms

3.1 Shared memory.

Need some means of controlling access. Basically only one process accessing memory at a time (mutual exclusion).
We can use:

        Signals - unreliable. Signals aren't queued, so some can get lost.
        Semaphores - low level. Make a mistake and everything goes to sleep.
        Event-counters - simpler to use than semaphores. Not very common. Like signals not guaranteed.


3.2 Message passing.

Various varieties :-

        Pipes or unbound sockets - only used by related processes. Easy to use. Synchronisation controlled by O/S
        (Sockets - Similar to pipes/file access. Can be used across network. Different varieties - guaranteed
         delivery (virtual circuits), unreliable (datagram)
        Rendezvous - similar to pipes/sockets but no buffering. Used in Occam and Ada.
        Shared files - similar to shared memory in virtual memory systems, since the file can be memory mapped. Can
         include record locking to enable synchronising.
        Named pipes - similar to pipes, but used by unrelated processes.
        Message passing. Similar to pipes, sockets, etc, but message boundaries preserved.


3.3 Remote Procedure Call (RPC).

Makes message passing look like a procedure call.




Unix Operating System: Interprocess Communication (IPC)                                                           3
 4 Shared Memory
The most efficient IPC mechanism is probably shared memory.

   .------------.        .------------.            .------------.
   |              |      |    Shared   |           |             |
   | Process A |-------->|    Memory   |---------->| Process B |
   |              |      |             |           |             |
     ------------          ------------              ------------

If we allow uncontrolled access we can get race conditions - the results depend on which process accesses memory
when. i.e. we can get different results when run several times.

For example, consider process A is a producer, and process B is a consumer. Process A is putting data into a buffer
(the shared memory), process B is removing it. To control access we have a shared variable called ItIsFree, which is
true when no process is accessing the buffer. The two processes might look like :-

          Process A                                       Process B
          LOOP                                            LOOP
            IF ItIsFree then                                IF ItIsFree then
               ItIsFree := FALSE                               ItIsFree := FALSE
               put data in buffer                              take data from buffer
               ItIsFree := TRUE                                ItIsFree := TRUE
            END                                             END
          END                                             END

Problems can occur if testing and setting ItIsFree is not a single operation, i.e. NOT ATOMIC, e.g.:

                     Process A                              Process B
                         |                                      |
            does test - ItIsFree is TRUE           does test - ItIsFree is TRUE
                set ItIsFree FALSE                     set ItIsFree FALSE
                 now both accessing the buffer at the same time

The section of code which accesses the shared memory is called the critical section. To ensure race conditions cannot
occur we need mutual exclusion - only one process is in its critical section at a time.

To totally avoid race conditions we need the following four conditions to be true :-

    1.    No two processes simultaneously in their critical sections.
    2.    No assumption should be made about speed or number of CPU's.
    3.    Processes outside their critical region should not be able to block other processes.
    4.    No process should have to wait forever to enter its critical section.


4.1 Access control - TAS instruction

To control access we want an indivisible instruction which can test and set a variable in one operation, e.g. TAS
(Test And Set) on the MC68000 family which tests bit 7 of an byte operand (copying its value to the Negative and Zero
flags) and sets it to 1, e.g.:

         label:          TAS variable                ; test the access variable
                         BNE label                   ; wait for zero
                         :
                           critical section of code using shared region
                         :
                         CLR.B variable              ; set to 0 to allow access

This is of little use since it uses busy-waiting (the TAS loop) and is a waste of CPU time.
Unix Operating System: Interprocess Communication (IPC)                                                     4
 4.2 Acess control - Sleep and Wakeup

What we want is that the process should sleep until the region is clear, then be woken up. That is we want two
instructions, i.e. the system calls:
  sleep            send process to sleep
  wakeup           wake process up. (i.e. make it ready to run)
Note that the Unix wakeup is subtlety different since it wakes all the processes sleeping on an event).

The mechanism is that when the producer has produced some output, it wakes the consumer and goes to sleep itself.
When the consumer has consumed the input it wakes the producer and sends itself to sleep. So the two processes
alternate and wake each other. Unfortunately wakeups can get lost. For example:

    1.    the producer reads the flag and finds it zero
    2.    but before it can go to sleep the consumer is scheduled
    3.    the consumer sends a wakeup, which gets lost, since nothing is asleep yet
    4.    the consumer then goes to sleep, waiting for the producer to wake it
    5.    the producer resumes and completes its sleep operation.

Both then sleep forever.
The solution is to store the wakeups - we then have the semaphore.


4.3 Access control - Semaphores

Invented by Dijkstra. They are low level, and easy to get wrong. A semaphore is a cardinal variable, with an associated
list of sleeping processes, plus two atomic operations which can be performed on it (apart from initialising it).

The two operations are DOWN(s) and UP(s) both will be system calls (s is                                     the semaphore.
Definition:-

DOWN(s):         If s = 0 then
                      send process to sleep
                 Else
                      decrement s
                 End

UP(s):           If any processes asleep on s then
                      wake one (i.e. make it ready to run)
                 Else
                      increment s
                 End

If s only takes the values 0 and 1 it is a binary semaphore, otherwise it is a general semaphore. Semaphores are only
used to enable processes to synchronise themselves. i.e. to ensure only one process enters a critical region at a time.
In typical use each process will have the following:

         DOWN(s)
          :
          :
         critical section
          :
          :
         UP(s)

Initially s is set to 1. If process A runs first and does a DOWN, s will be set to zero. Once A has completed the DOWN it
can be interrupted, even if it is still in its critical section. Suppose this happens and process B is set running. If it does
the DOWN it will be sent to sleep. Process A will eventually be set running again and will do an UP on exiting its critical
region. This will wake up B. Note we can have more than two processes.

Unix Operating System: Interprocess Communication (IPC)                                                             5
 4.4 Access control - event counters

Another synchronising mechanism is the event counter. This is similar to tickets that are given out in take away
restaurants. You are given a ticket with a number on it, then you wait until the event number (meals being ready)
reaches your number.
     Like the semaphore an event counter is a cardinal variable with an associated list of sleeping processes. Apart from
initialising the are 3 operations which can be performed on event counters :-

   READ(e)                  read the value of 'e'
   ADVANCE(e)                increment 'e'
   AWAIT(e,v)               wait until 'e' has a value of 'v' or more.

Like semaphores they are atomic system calls. For example in the producer/consumer situation, we could have:

       ine = 0; oute = 1;
       pseq = 0; cseq = 0;

then the producer would be

       LOOP
           :
         produce an item
         inc(pseq)
         AWAIT(oute, pseq)
         put item in the buffer
         ADVANCE(ine)
           :
       END

and the consumer would be

       LOOP
           :
         Inc(cseq)
         AWAIT(ine, cseq)
         get item from buffer
         ADVANCE(oute)
         :
       END




Unix Operating System: Interprocess Communication (IPC)                                                        6
 5 UNIX IPC

5.1 Pipes

Unix originally just had the pipe as the IPC mechanism. The pipe is a convenient high level mechanism which is created
with the pipe system call, e.g.:

     int pipe(int filedes[2]);

pipe creates a pair of file descriptors, pointing to a pipe i-node (similar to a file i-node), and places them in the array
pointed to by filedes; filedes[0] is for reading and filedes[1] is for writing. On success, zero is returned, on
error, -1 is returned and errno is set appropriately. For example:

       #include <unistd.h>
       int fd[2], rval;
       if ((rval = pipe(fd)) < 0) cout << " error creating pupe";

Once created the pipe can be used with read and write as though it is a file (can't use seek).

If a process reads from an empty pipe it blocks until some data is put into the pipe. If a process fills a pipe it blocks until
some bytes are removed from the pipe. The read command will return with zero bytes when end of file is met, e.g.
when the pipe has no writing processes left.

The pipe file-ids are passed to a child on forking to enable it to communicate with the parent, e.g.:

// pipe.cc - a parent piping a message to a child

//#include <errno.h>
#include <iostream.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void)
{
    int pid, p[2];
    char buffer2[] = "hello ", buffer1[100], N = 6;
    if (pipe(p) < 0)
        {
        cerr << "pipe error" << endl;
        exit(1);
        }
    if ((pid = fork()) == 0)
        {
        read(p[0], buffer1, N);
        cout << "child received: " << buffer1 << endl;
        }
    if ( pid > 0)
        {
        int status;
        cout << "parent sending: " << buffer2 << endl;
        write(p[1], buffer2, N);
        wait(&status);
        }
    return 0;
}




Unix Operating System: Interprocess Communication (IPC)                                                              7
A single pipe can be used to send information one way or the other, i.e.:

    ------------                                                            ------------
|                   | write(p[1])                read(p[0])|                            |
|                   |======>===========--==========>=======|                             |
|     parent        |                  ||                  |                  child     |
|                   |======<===========__==========<=======|                            |
|                   | read(p[0])                write(p[1])|                             |
    ------------                                                            ------------

Either the child or parent writes; not both at the same time. To have simultaneous two way communication you can have
two pipes, say p and q. It usual to close the ends of the pipe down you don't want, e.g. after the fork command the
parent can close q[0] and p[1], and the child can close q[1] and p[0]. Thus the parent writes into q and reads
from p, and the child writes to p and reads from q.



5.1.1 Non-blocking Read and Writes on Pipes

There are 2 ways to make sure a read or a write to a pipe does not block. One is to use fstat on the pipe, the other is
to use fcntl.

fstat allows you to find out how many characters are currently in the pipe. It is used as follows:

        #include <sys/stat.h>
        #include <sys/types.h>
        struct stat buf;
             :
        retval = fstat(fd, &buf);

where fd = a pipe descriptor (an integer). The values in buf are essentially the values contained in an i-node, and the
st_size field will return the file size, for pipes this will be the number of bytes in the pipe. If more than one process is
reading the pipe, you would have to be careful. By the time you have checked there is something in the pipe and read it,
some other process might have read it first and your process will then block.

The second method uses fcntl, as follows :-

        #include <fcntl.h>
             :
        stat = fcntl(fd, cmd, args);

where cmd selects the operation to be performed by fcntl, e.g.:

stat = fcntl(fd, F_SETFL, O_NDELAY)

sets the file or (pipe) pointed to by fd to no delay. Subsequent calls to write won't block if the pipe is full, they would
return a value of zero. Similarly, reads to a pipe return immediately. If the pipe was empty a value of zero is returned. This
means you can't tell if the pipe was empty or if the write end has been closed (eof condition). A change will be made
sometime so that read returns - 1 and EAGAIN into errno if the pipe is empty (but as far as I know it hasn't occurred
yet).




Unix Operating System: Interprocess Communication (IPC)                                                             8
 5.2 Named pipes

Pipes can only be used by related processes. To allow unrelated processes to communicate the named pipe was
introduced (it appears in a directory listing along with filenames and links).

A named pipe, or FIFO, is like an ordinary pipe in that it is a one-way first-in-first-out byte stream channel. They differ
from normal pipes in that they are permanent (like a file), have a Unix file name, owner, size, access rights, can be
opened, closed, deleted like a file, and can be used by unrelated processes.
   For the most part programming with FIFO's is the same as with pipes. The main difference is in initialisation. To create
a FIFO you can use the mknod command (at the shell prompt), e.g.

     $mknod myfifo p

Here myfifo is the name of the pipe. You can also specify permissions if you want. When you do an ls, the fifo has
a 'p' at the start of the line.

Alternatively, you can create the fifo in your program using the mknod system call, e.g.

       #include <fcntl.h>
            :
       if (mknod("myfifo", 010755, 0) < 0)
           perror("mknod failed");

or

       fd = open("myfifo", O_WRONLY);

which would open a fifo for writing. It will block until another process opens it for reading. You can open the fifo with a non
blocking call e.g.:

       if ( fd = open("myfifo", O_WRONLY | O_NDELAY)) < 0)
            perror("open failed on FIFO");

Future writes into the fifo will be non blocking. The open call will return -1 is another process isn't trying to read from the
fifo. Apart from O_WRONLY you could have O_RDONLY or O_RDWR.




Unix Operating System: Interprocess Communication (IPC)                                                              9
 Below is a simple example, sendmsg and rcvmsg; sendmsg sends messages supplied at the command line, e.g.:

       sendmsg hi there greetings to everyone

and rcvmsg reads the from the pipe and displays them.

//   Sendmsg.cc - send messages via a fifo to another program
//   create fifo first, i.e. mknod fifo p
//   then run rcvmsg, i.e. rcvmsg &
//   the run this, i.e. sendmsg hello sam how are you

#include      <iostream.h>
#include      <stdlib.h>
#include      <errno.h>
#include      <unistd.h>
#include      <fcntl.h>

const int MSGSIZE = 64;

extern int errno;
char *fifo = "fifo";

int main(int argc, char *argv[])
{
    int fd, j, nwrite;
    char msgbuf[MSGSIZE+1];

      if (argc < 2 )
         {
           cout << "Usage : sendmsg message..." << endl;
           exit(1);
         }
      // open fifo with O_NDELAY set, probably easier to use
      // blocking writes unless you have reasons for non-blocking
      if (( fd = open(fifo, O_WRONLY | O_NDELAY)) < 0)
         {
         cerr <<" FIFO open failed";
         exit(-1);
         }

      // send message
      for (j = 1; j < argc; j++)
         {
         if (strlen(argv[j]) > MSGSIZE)
              {
                cerr << "message too long " << argv[j] << endl;
                continue;
              }
         strcpy(msgbuf, argv[j]);
         if ((nwrite = write(fd, msgbuf, MSGSIZE+1)) <= 0)
            {
            if (nwrite == 0)      /* Full FIFO */
                  errno = EAGAIN;   /* Fake error */
            cerr << "mesage write failed" << endl;
            exit(-1);
            }
      }
      return 0;
}




Unix Operating System: Interprocess Communication (IPC)                                               10
 // rcvmsg.cc - receive message via FIFO pipe

#include      <iostream.h>
#include      <stdlib.h>
#include      <fcntl.h>
#include      <unistd.h>

const int MSGSIZE = 64;
char *fifo = "fifo";

int main(int argc, char *argv[])
{
    int fd;
    char msgbuf[MSGSIZE+1];
    // Open FIFO for reading and writing
    if ((fd = open(fifo, O_RDWR)) < 0 )
       {
       cerr << " FIFO open failure";
       exit(-1);
       }
    // Receive message(s) forever
    for (;;)
       {
       if (read(fd, msgbuf, MSGSIZE+1) < 0 )
          {
          cerr << " Message read failed";
          exit(-1);
          }
       // print message
       cout << "Message received: " << msgbuf << endl;
       }
    exit(0);
}


To run them, create the fifo first with mknod, run rcvmsg, then run sendmsg, i.e.:

c++ sendmsg.cc -o sendmsg
c++ rcvmsg.cc -o rcvmsg
mknod fifo p
rcvmsg &
sendmsg hello how are you

c++ is the GNU C++ compiler under LINUX and the & runs rcvmsg in the background. Remember to use kill to kill
the process (use ps to list the processes running and get the pid).


5.3 Record Locking


Useful for database files (not originally in UNIX). Typical use would be

               stat = lockf(fd, purpose, recsize)
                                  |          |
                                  |        size from current position
                        unlock, lock exclusively, test for lock

The record can contain any subsection of the file (or all of it). The call fails if it would cause deadlock.




Unix Operating System: Interprocess Communication (IPC)                                                        11
 6 Berkeley UNIX
Pipes are restricted to the same file system. Berkeley UNIX introduced sockets, which are like pipes but more versatile.
In particular, they can operate over networks.
   A socket is an end point for communication. A pair of sockets is similar to a pipe. A socket is identified by a socket
descriptor. Before a socket can be accessed across a network it must be bound to an address.

There are various types of socket e.g.

stream sockets              connection oriented, reliable byte stream (virtual circuit).
datagram sockets            unreliable connectionless message transfer.

Of the two, stream sockets are by far the easier to use. You don't have to worry about sequencing, acknowledging,
etc. The sequence of events is:-


     Server                                                   Client
Create a socket - socket                                      socket
Bind it to an address - bind
Wait for connections - listen
                                                     make a connection - connect
Accept connection                 - accept
Transfer data
                                  - read                        write
                                  - write                       read




7 System V UNIX
System V Unix introduced three extra IPC mechanisms - message passing, shared memory and semaphores.
(Semaphores are strictly a synchronising mechanism). They are powerful and complex, which makes them difficult to
use.
   The IPC object is identified by a key - a number. The programming interface has been made to look similar for the
three mechanisms.



7.1 Message Passing

Similar to pipes, except message boundaries are preserved. Need to first create a message queue using msgget, e.g.

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgqid, permflags;
key_t key;
msgqid = msgget(key, permflags);

We can then use msgsnd to send a message and msgrcv to receive a message
Also have msgctl to get status info, to change some limits associated with message queue or delete a queue.




Unix Operating System: Interprocess Communication (IPC)                                                        12
 7.3 Semaphores

These are similar to Dijkstra's semaphores but more complicated. Instead of single semaphores you can have an array
of them, e.g.:

|      |
|      |
|----|          --------------------------
|    o-------->| | | | |.... | | | | array of semaphores
|----|          --------------------------
|      |        each semaphore is a structure holding
|....|         semval - value of the semaphore (always +ve)
|....|         sempid - pid of last process to use semaphore
|      |       semcnt - no of processes waiting for semaphore to
  ----                  reach value > current value
              semzcnt - no of processes waiting for value to
                        reach zero

Because a process might be killed before it has done an 'up', it can set a SEM_UNDO flag in the semop call. When the
process exits, the kernel reverses the effects of every semaphore operation the process has done. The kernel
has a table with an entry for every process. Each entry points to a set of undo structures.

There are 3 operations (system calls) :-

semget            get a set of semaphores
semctl            semaphore control operations - initialise, find value, etc.
semop             semaphore operations - up, down


Semget has the following definition :-

#include <sys/sem.h>
int semget(key_t key, int nsem, int semflg);

it returns the semid
key is usually IPC_PRIVATE
nsem is the number of semaphores you want in the array
semflg can cause specific options to occur e.g.
     IPC_CREAT creates a semaphore id if doesn't already exist,
     the low order 9 bits are the semaphore operation permissions.

For example, to create a new semaphore :-

       semget(IPC_PRIVATE, num, IPC_CREAT | 0600);

Semctl has the following definition :-

#include <sys/sem.h>
int semctl( int semid, int semnum, int cmd, ....args..);

Provides a selection of semaphore control operations depending on cmd. Some possible values for cmd are :-

GETVAL            return the value of semval.
SETVAL            set the value of semval to arg.
GETPID            return the value of sempid
GETNCNT           return the value of semncnt
GETZCNT           return the value of semzcnt
IPC_RMID          remove the semaphore id specified by semid.


Unix Operating System: Interprocess Communication (IPC)                                                      13
 For example, to initialise a semaphore specified by semid[semno]:-

    semctl(semid, semno, SETVAL, val);

and to remove a semaphore

      semctl(semid, 0, IPC_RMID, 0);

Semop performs semaphore operations. Has the following definition :-

#include <sys/sem.h>
int semop(int semid, struct sembu *sops, unsigned int nsops);

Performs atomically an array of semaphore operations on the semaphore specified by semid. sops is a pointer to
an array of semaphore operation structures. (You should only need to carry out an operation on one semaphore
at a time). The contents of the structure is :-

   ushort semnum            the semaphore index in the array
   short sem_op             the operation to be done
   short sem_flg            flag


sem_op specifies one of three operations depending on whether it is negative, zero, or positive. I shall only describe a
subset of the possible options.

sem_op        = -1.       This causes a down operation to be performed. Namely, if sem_val is > 0 then sem_val is
           decremented. If sem_val is zero then the process is suspended and the count of the number of sleeping
           processes, semncnt, is incremented.
           The process sleeps until an up is done, semid is deleted, or the process receives a signal which it catches.

sem_op = +1                 This causes an up operation.

The case when sem_op = 0 appears to be used when you want the process to sleep if the semaphore value is non-
zero. (A sort of inverse definition for down and up. Semzcnt is used with this).

For example, the down operation would be:

       int down(sid);
          int sid;
       {
         struct sembuf s;              /* s: ushort sem_num
                                             short sem_op
                                             short sem_flg */
            s.sem_num = 0;
            s.sem_op = -1;
            s.sem_flg = SEM_UNDO;

            if (semop(sid, &s, 1) == -1)
                 {
                   perror("Down failed");
                   exit(1);
                 }
            else
                 return(0);
       }




Unix Operating System: Interprocess Communication (IPC)                                                        14
 7.4 Shared Memory

Associated with semaphores is a set of shared memory operations. Like the semaphore operations they have 3 system
calls :-
shmget (to get), shmat (to access), and shmdt (to detach).
They allow 2 or more processes to share a chunk of physical memory. Often achieved by mapping a file into
memory. The file bit means it can be opened, read, written by a process - but it will be a memory based file rather
than on disk (rather like a ramdisk).

Shmget Takes the form :

       shmid = shmget(key, size, flags);
                       |     |      |
                       |     |      permissions and actions reqd.
                       |     minimum reqd size (in bytes)
                       key value to identify shared memory

   e.g. shmget(IPC_PRIVATE, size, 0600);

Shmat To access the memory area you need to get its address :-

     char *memptr, *daddr, *shmat();
     memptr = shmat(shmid, daddr, shmflags);
       |              |      |         |
       |              |      |     specifies whether region is
address is returned   |      |           read-only etc
  in memptr or        |    address where you want to attach the memory
 (char *) -1 if       |      If 0 address is chosen by the system.
  an error           key

Once you have its address, the memory can be accessed in the usual way, e.g.:

       typedef struct {
            :
            int foo;
            :
       } SHMEM;
       SHMEM *shared; /* counts will point to the shared memory */
            :
       shmid = CreateShMem(&shared, sizeof(SHMEM));
       shared->foo := something;
       otherthing = shared->foo;
            :

A process detaches the shared memory from its address space using shmdt(memptr); when all processes detach from
the region, the kernel frees the region.


7.5 Message Passing

Messages allow processes to send data to other processes. Unlike pipes, message boundaries are preserved. There
are 4 system calls
msgget          gets a message queue
msgctl          has options to control the operation of the queue
msgsnd          sends a message (puts it in the queue)
msgrcv          receives a message.

You shouldn't need to use messages. For more information on the System V IPC mechanisms see "M. Bach : The
Design Of The Unix Operating System" or try man -k semaphores, etc.


Unix Operating System: Interprocess Communication (IPC)                                                   15

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:11
posted:12/7/2011
language:English
pages:15