inter process communication n.
Skip this Video
Download Presentation
Inter Process Communication

Loading in 2 Seconds...

play fullscreen
1 / 83

Inter Process Communication - PowerPoint PPT Presentation

  • Uploaded on

Inter Process Communication. Pipes/FIFO/Message Queues Semaphores Shared Memory. Why do processes communicate?. To share resources Client/server paradigms Inherently distributed applications Reusable software components etc. Types of IPC. Message Passing

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
Download Presentation

PowerPoint Slideshow about 'Inter Process Communication' - zilya

Download Now An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
inter process communication

Inter Process Communication

Pipes/FIFO/Message Queues


Shared Memory

why do processes communicate
Why do processes communicate?
  • To share resources
  • Client/server paradigms
  • Inherently distributed applications
  • Reusable software components
  • etc
types of ipc
Types of IPC

Message Passing

Pipes, FIFOs, and Message Queues


Mutexes, condition variables, read-write locks, file and record locks, and semaphores

Shared memory

Remote Procedure Calls

Solaris doors and Sun RPC

what is ipc
What is IPC?

Each process has a private address space. Normally, no process can write to another process’s space. How to get important data from process A to process B?

Message passing between different processes running on the same operating system is IPC

Synchronization is required in case of IPC through shared memory or file system


Pipes are the oldest form of UNIX System IPC and are provided by all UNIX systems

Most commonly used form of IPC

Historically, they have been half duplex (i.e., data flows in only one direction).

Because they don’t have names, pipes can be used only between processes that have a common ancestor.

Normally, a pipe is created by a process, that process calls fork, and the pipe is used between the parent and the child.

unix pipes
UNIX Pipes

Parent process, p1

Child process, p2

Info to be


Info copy

int p[2];


write(p[1], “hello”, size);


read(p[0], inbuf, size);


pipe for p1 and p2


write function

read function

FIFO buffer

size = 4096 characters


#include <unistd.h>

int pipe(int fd[2]); returns 0 if OK, else -1

fd[0]-> for reading, fd[1] is for writing


Pipes are rarely used in a single process. They are generally used between parent and child


main ()


int i;

int p[2];

pid_t ret;

pipe (p); //creating pipe

char buf[100];

ret = fork ();

if (ret == 0)


write (p[1], "hello", 6);//writing to parent through pipe


if (ret > 0)


read (p[0], buf, 6); //reading from child via pipe

printf ("Child Said:%s\n", buf); //printing to stdout



who sort

Create a pipe in the parent

Fork a child

Duplicate the standard output descriptor to write end of pipe

Exec ‘who’ program

In the parent wait for the child.

Duplicate the standard input descriptor to read end of pipe

Exec ‘sort’ program

who sort1

main ()

{ int i;

int p[2];

pid_t ret;

pipe (p);

ret = fork ();

if (ret == 0)


close (1);

dup (p[1]);

close (p[0]);

execlp (“who", “who", (char *) 0);


if (ret > 0)


close (0);

dup (p[0]);

close (p[1]);

wait (NULL);

execlp (“sort", “sort", (char *) 0);


dup and dup2 functions
dup and dup2 Functions

#include <unistd.h>

int dup(int filedes);

int dup2(int filedes, int filedes2); Both return: new file descriptor if OK, 1 on error

The new file descriptor returned by dup is guaranteed to be the lowest-numbered available file descriptor.

With dup2, we specify the value of the new descriptor with the filedes2 argument. If filedes2 is already open, it is first closed. If filedes equals filedes2, then dup2 returns filedes2 without closing it.


#include <stdio.h>

FILE *popen(const char *cmdstring, const char *type);

Returns: file pointer if OK, NULL on error

int pclose(FILE *fp);


Popen does

creating a pipe, forking a child, closing the unused ends of the pipe, executing a shell to run the command, and waiting for the command to terminate

fp = popen("ls *.c", "r");

Not to be used in this course

name spaces
Name Spaces

When two unrelated processes use some type of IPC to exchange information, the IPC object must have a name or identifier of some form

The set of possible names for a given type of IPC is called its name space

FIFOs have pathname in the file system as identifier


Create a FIFO

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode) //returns 0 if OK or -1

Ex: if( mkfifo("fifo1", 0666)<0) perror();

mkfifo returns error ‘EEXIST’ if the FIFO already exists at the given path


Once a FIFO is created, it should be opened either for reading or writing

wfd=open("fifo1",O_WRONLY); or

FILE *fp = fopen(“fifo1”, “w”);

FIFO can’t be opened both for reading and writing at the same time

Unlike pipe, FIFO is not deleted as soon as all the processes referring to it exit. It has to be explicitly deleted from system.


fifos between parent and child2
FIFOs between parent and child

Swap these two calls and see

non blocking option
Non-blocking option

A descriptor can be set non-blocking in one of the two ways


writing to pipe fifo when pipe fifo is open for reading
Writing to pipe/fifo when pipe/fifo is open for reading

If data size is less than or equal to PIPE_BUF, the write is atomic i.e. either all the data is written or no data written

If there is no room in the pipe for the requested data (<PIPE_BUF), by default it blocks.

If O_NONBLOCK option is set, EAGAIN error is returned

If data is >PIPE_BUF and O_NONBLOCK option is set, even if 1 byte space is available in the pipe, it will write that much data and return

Atomicity is not guaranteed

message queues
Message Queues

A message queue is a linked list of messages stored within the kernel and identified by a message queue identifier

Any process with adequate privileges can place the message into the queue and any process with adequate privileges can read from queue

There is no requirement that some process must be waiting to receive message before sending the message

fifo vs message queues
FIFO Vs Message Queues
  • Data is passed as a stream of bytes in FIFO where is as in MsgQs message boundaries are preserved.
  • FIFOs require that the writer and reader process be present to pass data where as in MsgQs it is not required
  • FIFOs follow ‘first in first out’ order of passing data where as in MsgQs messages can be retrieved in any order
  • Pipes/FIFO are process persistent; MsgQs are kernel persistent
message queues1
Message Queues

Every message queue has following structure in kernel


struct ipc_perm {

uid_t uid; /* owner's effective user id */

gid_t gid; /* owner's effective group id */

uid_t cuid; /* creator's effective user id */

gid_t cgid; /* creator's effective group id */

mode_t mode; /* access modes */ . . . };

Permission Bit

user-read 0400

user-write (alter) 0200

group-read 0040

group-write (alter) 0020

other-read 0004

other-write (alter) 0002

message queues3
Message Queues

Firstmsgget is used to either open an existing queue or create a new queue

#include <sys/msg.h>

int msgget(key_t key, int flag);

Returns: message queue ID if OK, 1 on error

Key value can be IPC_PRIVATE, key generated by ftok() or any key (long integer)

Flag value must be

IPC_CREAT if a new queue has to be created

IPC_CREAT and IPC_EXCL if want to create a new a queue but don’t reference existing one

key values
Key Values

The server can create a new IPC structure by specifying a key of IPC_PRIVATE

Kernel generates a uniqe id

The client and the server can agree on a key by defining the key in a common header.

The client and the server can agree on a pathname and project ID and call the function ftok to convert these two values into a key.

#include <sys/ipc.h>

key_t ftok(const char *path, int id);

The path argument must refer to an existing file. Only the lower 8 bits of id are used when generating the key.

message queues4
Message Queues

When a new queue is created, the following members of the msqid_ds structure are initialized.

The ipc_perm structure is initialized

msg_qnum, msg_lspid, msg_lrpid, msg_stime, and msg_rtime are all set to 0.

msg_ctime is set to the current time.

msg_qbytes is set to the system limit.

On success, msgget returns the non-negative queue ID. This value is then used with the other three message queue functions.


Each message is composed of a positive long integer type field, and the actual data bytes. Messages are always placed at the end of the queue.

Messaeg Template

Most applications define their own message structure according to the needs of the application

sending messages
Sending Messages
  • #include <sys/msg.h>

int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);

  • msqid is the id returned by msgget sys call
  • The ptr argument is a pointer to a message structure
  • Nbytes is the length of the user data i.e. sizeof(struct mesg) – size of(long). Length can be zero.
  • A flag value of 0 or IPC_NOWAIT can be specified
  • mssnd() is blocked until one of the following occurs
    • Room exists for the message
    • Message queue is removed (EIDRM error is returned)
    • Interrupted by a signal ( EINTR is returned)
receiving messages
Receiving Messages
  • ptr points to the message structure where message will be stord
  • Length points to the size available on the message structure excluding size of (long)
  • Type indicates the message desired on the message queue
  • Flag can be 0 or IPC_NOWAIT or MSG_NOERROR
receiving messages1
Receiving Messages
  • The type argument lets us specify which message we want.
    • type == 0: The first message on the queue is returned.
    • type > 0:The first message on the queue whose message type equals type is returned.
    • type < 0:The first message on the queue whose message type is the lowest value less than or equal to the absolute value of type is returned.
  • A nonzero type is used to read the messages in an order other than first in, first out.
    • Priority to messages, Multiplexing
receiving messages3
Receiving Messages
  • IPC_NOWAIT flag makes the operation nonblocking, causing msgrcv to return -1 with errno set to ENOMSG if a message of the specified type is not available.
  • If IPC_NOWAIT is not specified, the operation blocks until
    • a message of the specified type is available,
    • the queue is removed from the system (-1 is returned with errno set to EIDRM)
    • a signal is caught and the signal handler returns (causing msgrcv to return 1 with errno set to EINTR).
receiving messages4
Receiving Messages
  • If the returned message is larger than nbytes and the MSG_NOERROR bit in flag is set, the message is truncated.
    • no notification is given to us that the message was truncated, and the remainder of the message is discarded.
  • If the message is too big and MSG_NOERROR is not specified, an error of E2BIG is returned instead (and the message stays on the queue).
control operations on message queues
Control Operations on Message Queues
  • #include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf );

  • IPC_STAT: Fetch the msqid_ds structure for this queue, storing it in the structure pointed to by buf.
  • IPC_SET: Copy the following fields from the structure pointed to by buf to the msqid_ds structure associated with this queue: msg_perm.uid, msg_perm.gid, msg_perm.mode, and msg_qbytes.
  • IPC_RMID: Remove the message queue from the system and any data still on the queue. This removal is immediate.
    • Any other process still using the message queue will get an error of EIDRM on its next attempted operation on the queue.
    • Above two commands can be executed only by a process whose effective user ID equals msg_perm.cuid or msg_perm.uid or by a process with superuser privileges
multiplexing messages
Multiplexing Messages
  • Possibility of dead lock
system v semaphores
System V Semaphores
  • A semaphore is a primitive used to provide synchronization between various processes (or between various threads in a given process)
  • Binary Semaphores: a semaphore that can assume only values 0 or 1
  • Counting Semaphores: semaphore is initialized to N indicating the number of resources
system v semaphores1
System V Semaphores
  • Semaphores are maintained by kernel
semaphore operations
Semaphore operations
  • Create a semaphore and initialize it
    • should be atomically done
  • Wait for a semaphore: This tests the value of the semaphore. waits (blocks) if the value is less than or equal to 0 and then decrements the semaphore value once it is greater than 0 (aka P, lock, wait)
    • Testing and decrementing should be a single atomic operation
  • Post a semaphore. This increments the semaphore value. If any processes are blocked waiting for this semaphores’s value o be greater than 0, one of those processes are woken up (aka V, unlock, signal)
producer consumer problem
Producer Consumer Problem
  • Producer produces one item and keeps in buffer.
  • Consumer removes that item for processing
  • How to synchronize?
producer consumer problem1
Producer Consumer Problem
  • Semaphore put controls whether the producer can place an item into the shared buffer
  • Semaphore get controls whether the consumer can remove an item from the shred buffer
system v semaphores2
System V Semaphores
  • Add one more level of detail by defining “a set of counting semaphores”
  • When we say System V semaphore it refers to a set of couting semaphores ( max size of set is 25)
system v semaphores3
System V Semaphores
  • Kernel maintains the following structure for every set
  • Sem structure maintains info about each semaphore. Sem_base contains pointer to an array of these structures
system v semaphores4
System V Semaphores
  • Kernel structure for a semaphore set having 2 counting semaphores
creating semaphores
Creating Semaphores
  • The number of semaphores in the set is nsems. If a new set is being created, we must specify nsems. If we are referencing an existing set, we can specify nsems as 0.
  • When a new set is created, the following members of the semid_ds structure are initialized.
    • The ipc_perm structure
    • sem_otime is set to 0.
    • sem_ctime is set to the current time.
    • sem_nsems is set to nsems.
initializing a semaphore value
Initializing a semaphore value
  • Semnum specifies which semaphore (0,1,2 …)
  • Semun union is used for some commands
  • This union desn’t appear in any application, it should be declared in your program
testing whether semaphore has been initilized
Testing whether semaphore has been initilized
  • When process P1 creates semaphore sem_otime is set to zero.
  • When P1 calls semctl to initialize and then semop, sem_otime is set to current time.
  • When process P2 checks sem_otime is non zero it understands that semaphore has been initialized.
semctl commands
semctl() commands
  • IPC_STAT, IPC_SET, IPC_RMID same as in message queues
  • GETVAL: Return the value of semval for the member semnum.
  • SETVAL: Set the value of semval for the member semnum. The value is specified by arg.val.
  • GETPID: Return the value of sempid for the member semnum.
  • GETNCNT: Return the value of semncnt for the member semnum.
  • GETZCNT: Return the value of semzcnt for the member semnum.
  • GETALL: Fetch all the semaphore values in the set. These values are stored in the array pointed to by arg.array.
  • SETALL: Set all the semaphore values in the set to the values pointed to by arg.array
semaphore opearions
Semaphore opearions
  • Opsptr points to an array of following structure
  • nops specifies number of structures in the array
  • Semop gurantees that either all these operations are done or none are done
semaphore operations1
Semaphore operations
  • The operation on each member of the set is specified by the corresponding sem_op value. This value can be negative, 0, or positive.
  • If sem_op>0:
    • returning of resources by the process.
    • Semval+=sem_op
    • If the SEM_UNDO flag is specified, semadj -=sem_op
    • subtracted from the semaphore's adjustment value for this process.
semaphore operations2
Semaphore operations
  • If sem_op <0
    • obtain resources that the semaphore controls.
  • If semval>= |sem_op|
    • the resources are available
    • Semva -= |sem_op|
    • If the SEM_UNDO flag is specified,
    • semadj += sem_op
    • added to the semaphore's adjustment value for this process.
semaphore operations3
Semaphore operations
  • If semval < |sem_op|
    • the resources are not available
    • If IPC_NOWAIT is specified, semop returns with an error of EAGAIN.
    • If IPC_NOWAIT is not specified, the semncnt value for this semaphore is incremented (since the caller is about to go to sleep), and the calling process is suspended until one of the following occurs.
      • Semval>=|sem_op| i.e. some other process has released some resources. Semncnt--
      • The semaphore is removed from the system. In this case, the function returns an error of EIDRM.
      • A signal is caught by the process, and the signal handler returns. and the function returns an error of EINTR. semncnt--
semaphore operations4
Semaphore operations
  • If sem_op = 0,
    • this means that the calling process wants to wait until the semaphore's value becomes 0.
  • If the semaphore's value is currently 0, the function returns immediately.
  • If the semaphore's value is nonzero, the following conditions apply.
    • If IPC_NOWAIT is specified, return is made with an error of EAGAIN.
    • If IPC_NOWAIT is not specified, semzcnt++, and the calling process is suspended until one of the following occurs.
      • The semaphore's value becomes 0. semzcnt--
      • The semaphore is removed from the system. In this case, the function returns an error of EIDRM.
      • A signal is caught by the process, and the signal handler returns. the function returns an error of EINTR. Semzcnt--
semval adjustment on process termination
Semval adjustment on process termination
  • it is a problem if a process terminates while it has resources allocated through a semaphore.
  • Whenever we specify the SEM_UNDO flag for a semaphore operation and we allocate resources (a sem_op value less than 0), the kernel remembers how many resources we allocated from that particular semaphore (the absolute value of sem_op).
  • When the process terminates, either voluntarily or involuntarily, the kernel checks whether the process has any outstanding semaphore adjustments and, if so, applies the adjustment to the corresponding semaphore value.
  • If we set the value of a semaphore using semctl, with either the SETVAL or SETALL commands, the adjustment value for that semaphore in all processes is set to 0.
shared memory
Shared Memory
  • Shared memory allows two or more processes to share a given region of memory.
  • This is the fastest form of IPC, because the data does not need to be copied between the client and the server
message passing
Message Passing
  • Takes 4 copies to transfer data between two processes
shared memory1
Shared Memory
  • Takes only two steps
  • Kernel is not involved in transferring data but it is involved in creating shared memory
memory mapped files1
Memory mapped files
  • proto argument for read-write access is PROT_READ|PROTO_WRITE
  • Flags must be either MAP_SHARED or MAP_PRIVATE
  • MAP_SHARED is used to share memory with other processes
why mmap
Why mmap()?
  • It makes file handling easy. We open some file and map that file into our process address space. To write or read from file we don’t have to use read(), write() or lseek()
  • Another use is to provide shared memory between unrelated processes
counter example
Counter Example
  • Closing file has no effect on memory mapping
  • Memory mappings are propagated to newly created child
system v shared memory
System V Shared Memory
  • For every shared memory segment kernel maintains the following structure
system v shared memory1
System V Shared Memory
  • Creating or opening shared memory
    • #include <sys/shm.h>
    • int shmget(key_t key, size_t size, int flag);
    • Size is given as zero if we are referencing existing shared memory segment
    • When a new segment is created, the contents of the segment are initialized with zeros

Size of memory in bytes

attaching shared memory to a process
Attaching shared memory to a process
  • Once a shared memory segment has been created, a process attaches it to its address space by calling shmat.
    • #include <sys/shm.h>
    • void *shmat(int shmid, const void *addr, int flag); Returns: pointer to shared memory segment if OK, 1 on error
  • The address in the calling process at which the segment is attached depends on the addr argument
  • If addr is 0, the segment is attached at the first available address selected by the kernel. This is the recommended technique.
dettaching shared memory from a process
Dettaching shared memory from a process
  • #include <sys/shm.h>
  • int shmdt(void *addr);
  • this does not remove the identifier and its associated data structure from the system.
  • The identifier remains in existence until some process (often a server) specifically removes it by calling shmctl with a command of IPC_RMID.
  • #include <sys/shm.h>
  • int shmctl(int shmid, int cmd, struct shmid_ds *buf);
  • IPC_STAT, IPC_SET same as other XSI IPC.
  • Remove the shared memory segment set from the system. The segment is not removed until the last process using the segment terminates or detaches it.
memory mapping of dev zero
Memory Mapping of /dev/zero
  • Shared memory can be used between unrelated processes. But if the processes are related, some implementations provide a different technique.
  • The device /dev/zero is an infinite source of 0 bytes when read. This device also accepts any data that is written to it, ignoring the data.
  • An unnamed memory region is created and is initialized to 0.
  • Multiple processes can share this region if a common ancestor specifies the MAP_SHARED flag to mmap.

void *area;

if ((fd = open("/dev/zero", O_RDWR)) < 0) perror("open error");

if ((area = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) perror();


anonymous memory mapping
Anonymous Memory Mapping
  • A facility similar to the /dev/zero feature. To use this facility, we specify the MAP_ANON flag to mmap and specify the file descriptor as -1.
  • The resulting region is anonymous (since it's not associated with a pathname through a file descriptor) and creates a memory region that can be shared with descendant processes.
  • this call, we specify the MAP_ANON flag and set the file descriptor to -1.

void *area;

if ((area = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) perror();

shared memory2
Shared Memory
  • Between unrelated processes:
    • XSI or System V shared memory
    • can use mmap to map the same file into another process address spaces using the MAP_SHARED flag.
  • Between related processes
    • Memory mapping of /dev/zero
    • Unonymous memory mapping

Pipes and FIFOS

  • System V Message Queues, Semaphores, Shared Memory
  • Posix Message Queues, semaphores, shared memory