Sunteți pe pagina 1din 41

UNIT IV Syllabus

 Interprocess Communication - Introduction to IPC, IPC between processes


on a single computer system, IPC between processes on different systems,
 pipes-creation, IPC between related processes using unnamed pipes,
 FIFOs-creation, IPC between unrelated processes using FIFOs (Named pipes),
differences between unnamed and named pipes, popen and pclose library
functions.
 Message Queues- Kernel support for messages, APIs for message queues,
client/server example.
 Semaphores-Kernel support for semaphores, APIs for semaphores, file
locking with semaphores.

05/02/2020 JBIET
Introduction to IPC
• Inter process communication (IPC) is used for exchanging data between
multiple threads in one or more processes or programs.
• Operating systems provide facilities/resources for inter-process
communications (IPC), such as message queues, semaphores, and
shared memory.
• A complex programming environment often uses multiple cooperating
processes to perform related operations These processes must
communicate with eachother and share resources and information. The
kernel must provide mechanismsthat make this possible. These
mechanisms are collectively referred to asinterprocess communication.

05/02/2020 JBIET
Why IPC?
• Here, are the reasons for using the interprocess communication
protocol for information sharing:
• It helps to speedup modularity
• Computational
• Privilege separation
• Convenience
• Helps operating system to communicate with each other and
synchronize their actions.

05/02/2020 JBIET
IPC in Unix

05/02/2020 JBIET
IPC between processes on a single
computer system
The first case is easier to implement because processes can share memory either in the user space or
in the system space. This is equally true for uniprocessors and multiprocessors.
IPC between processes on a Single System
Most of this chapter is focused on IPC on a single computer system, including four general
approaches:
 Shared memory
 Messages
 Pipes
 Sockets

The synchronization objects considered in the previous chapter normally work across the process
boundaries (on a single computer system). There is one addition necessary however: the
synchronization objects must be named. The handles are generally private to the process, while the
object names, like file names, are global and known to all processes.
h = init_CS("xxx"); h = init_semaphore(20,"xxx"); h = init_event("xxx"); h = init_condition("xxx"); h =
init_message_buffer(100,"xxx");

05/02/2020 JBIET
IPC between processes on different
systems
The computers do not share physical memory, they are connected via I/O device(for example serial
communication or Ethernet). Therefore the processes residing in different computers can not use memory as
a means for communication.

IPC between processes on different systems


IPC is Inter Process Communication, more of a technique to share data across different processes within
one machine, in such a way that data passing binds the coupling of different processes.
The first, is using memory mapping techniques, where a memory map is created, and others .
open the memory map for reading/writing... The second is, using sockets, to communicate with one
another...this has a high overhead, as each process would have to open up the socket, communicate
across... although effective The third, is to use a pipe or a named pipe, a very good example

05/02/2020 JBIET
What is a Pipe?
• A pipe is a serial communication device (i.e., the data is read in the order in which it
was written),which allows a unidirectional communication. The data written to end is
read back from the other end.
• The pipe is mainly used to communicate between two threads in a single process or
between parent and
• child process.
• Pipes can only connect the related process. In shell, the symbol can be used to create a
pipe. In pipes the capacity of data is limited. (i.e.) If the writing process is faster than
the reading process which consumes the data, the pipe cannot store the data. In this
situation the writer process will block until more capacity becomes available. Also if the
reading process tries to read data when there is no data to read, it will be blocked until
the data becomes available. By this, pipes automatically synchronize the two process.

05/02/2020 JBIET
05/02/2020 JBIET
Pipe program : To creates, writes to,
and reads from a pipe

05/02/2020 JBIET
IPC between related processes using
unnamed pipes:
fork() and pipe()

05/02/2020 JBIET
pipes-creation
Example to show how to create and use a pipe :

The program creates a pipe and then forks. Now both parent and
//pipes.c if(fork_result==(pid_t)0)
child process will have its own file descriptors for reading and
#include<unistd.h> {
#include<stdlib.h> close(0); dup(file_pipes[0]); writing. Therefore totally there are four file descriptors.
#include<stdio.h> close(file_pipes[0]); The child process will close its standard input with close(0) and calls
#include<string.h> duo(file_pipes[0]). This will duplicate the file descriptor associated
int main() close(file_pipes[1]);
with the read end. Then child closes its original file descriptor. As
{ execlp("od","od","-c",(char *)0);
child will never write, it also closes the write file descriptor,
int data_processed; exit(EXIT_FAILURE);
int file_pipes[2]; }
file_pipes[1]. Now there is only one file descriptor 0 associated
const char some_data[]= "123"; else with the pipe that is standard input. Next, child uses the exec to
pid_t fork_result; { invoke any program that reads standard input. The od command
if(pipe(file_pipes)==0) close(file_pipes[0]); will wait for the data to be available from the user terminal.
{ fork_result=fork(); data_processed=write(file_pipes[1],
some_data,strlen(some_data)); Since the parent never read the pipe, it starts by closing the read
if(fork_result==(pid_t)-1) {
close(file_pipes[1]); end that is file_pipe[0]. When writing process of data has been
fprintf(stderr,"fork failure");
printf("%d -wrote %d bytes\n", finished, the write end of the parent is closed and exited. As there
exit(EXIT_FAILURE); (int)getpid(),data_processed); } }
} exit(EXIT_SUCCESS);
are no file descriptor open to write to pipe, the od command will
} be able to read the three bytes written to pipe, meanwhile the
reading process will return 0 bytes indicating the end of the file .

05/02/2020 JBIET
05/02/2020 JBIET
File Descriptor Table(dup(),dup2()

05/02/2020 JBIET
FIFOs-creation
• A FIFO (First In First Out) is a one-way flow of data. FIFOs have a name, so unrelated processes can share the
FIFO.
• FIFOs are sometimes called named pipes. Pipes can be used only between related processes when a common
ancestor has created the pipe. FIFOs can be used to duplicate an output stream in a series of shell commands.
• FIFOs is used to send data between a client and a server.·Data written to a FIFO file are stored in a fixed-size
buffer and retrieved in a first-in-first-out order.
• Function prototype for FIFO :
• #include <sys/types.h>
• #include <sys/stat.h>
• int mkfifo( const char* path_name, mode_t mode);
• The mode argument is just like in open ( ).
• When a process opens a FIFO file for read-only, the kernel will block the process until there is another process
that opens the same file for write. If a process opens a FIFO for write, it will be blocked until another process
opens the FIFO for read. This provides a method for process synchronization.

05/02/2020 JBIET
FIFOs-Creation
• If a process writes to a FIFO that is full, the process will be blocked
until another process has read data from the FIFO to make room for
new data in the FIFO.
• If a process attempts to read data from a FIFO that is empty, the
process will be blocked until another process writes data to the FIFO.
• If a process does not desire to be blocked by a FIFO file, it can specify
the O_NONBLOCK flag in the open call to the FIFO file.
• If two processes are to communicate via a FIFO file, it is important
that the writer process closes its file descriptor when it is done, so
that the reader process can see the end-of-file condition.
05/02/2020 JBIET
05/02/2020 JBIET
Producers and
Consumers:
Once the FIFO has been
created, a process can start up
and open it for reading or
writing using the standard
open() system call.
I'll present here two programs
which will send data through a
FIFO. One is speak.c which
sends data through the FIFO,
and the other is called tick.c,
as it sucks data out of the FIFO.

05/02/2020 JBIET
Tick.c
What speak does is create the FIFO, then try
to open() it.
.ow, what will happen is that the open() call
will block until some other process opens the
other end of the pipe for reading. (There is a
way around this—see O_NDELAY, below.)
That process is tick.c30, shown here:

05/02/2020 JBIET
05/02/2020 JBIET
IPC between unrelated processes
using FIFOs (Named pipes)
• Pipes are meant for inter-related processes only. Pipes can’t be used
for unrelated processes communication, say, if we want to execute
one process from one terminal and another process from another
terminal, it is not possible with pipes.
• Named pipe is meant for communication between two or more
unrelated processes and can also have bi-directional communication.
• The bi-directional communication i.e., the client sending message to
the server and the server receiving the message and sending back
another message to the client using the same named pipe.

05/02/2020 JBIET
Named pipe is meant for
communication between two or more
unrelated process:

https://www.tutorialspoint.com/inter_process_communication
/inter_process_communication_named_pipes.htm
05/02/2020 JBIET
Differences between unnamed and
named pipes
• What distinguishes named pipes from unnamed pipes is that
● They exist as directory entries in the file system and therefore have
associated permissions and ownership2 .
● They can be used by processes that are not related to each other.
● They can be created and deleted at the shell level or at the
programming level.

05/02/2020 JBIET
popen and pclose library functions

05/02/2020 JBIET
//shpipe3.c
#include <stdio.h>
#include <unistd.h>
#include < stdlib.h>
#include <limits.h>
int main(int argc, char* argv[])
{ int nbytes; FILE *fin; // read-end of pipe FILE *fout; // write-end of pipe char
buffer[PIPE_BUF]; // buffer for transferring data
if ( argc < 3 )
{ fprintf(stderr, "Usage: %s command1 command2\n", argv[0]); exit(1); }
if ( (fin = popen(argv[1], "r")) == NULL )
{ fprintf(stderr, "popen() failed\n"); exit(1); }
if ( (fout = popen(argv[2], "w")) == NULL )
{ fprintf(stderr, "popen() failed\n"); exit(1); }
while ( (nbytes = read(fileno(fin), buffer,
05/02/2020 JBIET PIPE_BUF)) > 0 )
Message Queues
A message queue is a linked list of messages stored within the kernel and identified by a message queue
identifier. Generally message queue is called a queue and its identifier a queue ID. There are 2 forms of message
queue. One is System V message queue and another one is POSIX message queue. POSIX message queue is newer
than System V message queue.
Each message on queue has following attributes:
·         long integer type
·         length of data portion of message
·         data
A message queue allows one or more processes to write messages, which will be read by one or more reading processes.

Sys V Message Queue System calls:

msgget: The function returns the message queue identifier associated to the value of the keyargument.

Syntax:          #include <sys/msg.h>
                        int msgget(
                                    key_t key,      //key
                                    int flags);        //creation flags
                        It returns identifier on success or -1 on error.
flag options:
IPC_CREAT – creates queue if it does not already exist.
05/02/2020 JBIET
IPC_EXCL – fail if the file already exists.
msgctl: control message queue

Syntax:          #include <sys/msg.h>


                        int msgctl(
                                    int msqid,       //identifier
                                    int cmd,          //command
                                    struct msqid_ds *data);        //data for a command
                        Returns 0 on success or -1 on error.
Struct msqid_ds – structure for msgctl
                        struct msqid_ds{
                                    struct ipc_perm msg_perm;//permission structure
                                    msgqnum_t msg_qnum;     //no. of messages currently on queue
                                    msglen_t msg_qbytes;        //max. no. of bytes allowed on queue
                                    pid_t msg_lspid;                   //processs ID of last msgsnd
                                    pid_t msg_lrpid;                    //process ID of last msgrcv
                                    time_t msg_stime;                //time of last msgsnd
                                    time_t msg_rtime;                 //time of last msgrcv
                                    time_t msg_ctime;                //time of last msgctl change
                                    };
cmd options:
            IPC_RMID – remove the queue associated with msqid
            IPC_STAT – Fill the structure pointed to by data with information about the queue.
            IPC_SET – Set four properties of the queue
                                    msg_perm.uid
                                    msg_perm.gid
05/02/2020 JBIET
                                    msg_perm.mode
msgsnd: To send or receive a message, the calling process allocates a structure of a     message.
Syntax:          #include sys/msg.h>
                        int msgsnd(
                                    int msqid,                   //identifier
                                    const void *msgp,     //message
                                    size_t msgsize,         //size of message
                                    int flags);                    //flags
                        Returns 0 on success or -1 on error.
msgrcv: To send or receive a message, the calling process allocates a structure of a message.
Syntax:          #include sys/msg.h>
                        int msgrcv(
                                    int msqid,                   //identifier
                                     void *msgp,              //message
                                    size_t mtextsize,       //size of mtext buffer
                                    long msgtype,           //message type requested
                                    int flags);                    //flags
                        Returns no. of bytes placed in mtext on success or -1 on error.
Struct msg – structure for msgsnd and msgrcv
                       struct msg{
                                    long mtype;                           //message type
                                    char mtext[MTEXTSIZE];    //message text
                                    };
flag options:
      IPC_NOWAIT – for immediate return if no message of the requested type is on the queue.
      MSG_EXCEPT – used with msgtype greterthan 0 to read the first message on the queue with message type that differs
from msgtype.05/02/2020 JBIET
Kernel support for messages

05/02/2020 JBIET
APIs for message queues

05/02/2020 JBIET
client/server example

05/02/2020 JBIET
Server :- A program that submits messages to a message queue

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

int main (void) {


        key_t ipckey;
        int mq_id;
        struct { long type; char text[100]; } mymsg;
        /* Generate the ipc key */
        ipckey = ftok("/tmp/foo", 42);
        printf("My key is %d\n", ipckey);
        /* Set up the message queue */
        mq_id = msgget(ipckey, IPC_CREAT | 0666);
        printf("Message identifier is %d\n", mq_id);
        /* Send a message */
        memset(mymsg.text, 0, 100); /* Clear out the space */
        strcpy(mymsg.text, "Hello, world!");
        mymsg.type = 1;
        msgsnd(mq_id, &mymsg, sizeof(mymsg), 0);
05/02/2020 JBIET
}
Client :- Code to retrieve a message from a queue
 #include <sys/types.h>#include <sys/msg.h>
#include <sys/ipc.h>
#include <string.h>
#include <stdio.h> 
int main (void)
{         key_t ipckey;  
      int mq_id;       
struct { long type; char text[100]; } mymsg;       
int received;       
  /* Generate the ipc key */        ipckey = ftok("/tmp/foo", 42);        printf("My key is %d\n", ipckey);    
     /* Set up the message queue */        mq_id = msgget(ipckey, 0);    
    printf("Message identifier is %d\n", mq_id);     
    received = msgrcv(mq_id, &mymsg, sizeof(mymsg), 0, 0);       Output of the client and server code:
 sunbox$ ./mq_server
  printf("%s (%d)\n", mymsg.text, received) My key is 704654099
;} Message identifier is 2
sunbox$ ./mq_client
My key is 704654099
Message identifier is 2
Hello, world! (104)

05/02/2020 JBIET
Semaphores
• A semaphore is a kernel object that one or more threads of execution can acquire or
release for the purposes of synchronization or mutual exclusion.
• ·A critical section is a section of code which only one process at a time can be
executing.
• Semaphores are integer value objects that supports two atomic operations : P ( )for
wait and V ( ) for signal.
1. The P ( ) operation decrements the value of the semaphore and blocks if its new
value is less than zero.
2. The V ( ) operation increments its value ; if the resulting value becomes greater
than or equal to zero.
The simplest semaphore is a variable that can take only the values 0 and 1. It is called
binary semaphore.
05/02/2020 JBIET
• The kernel uses semaphores internally to synchronize its operations.
• ·All the Linux semaphore functions operate on array of general
semaphores rather than a single binary semaphore.·
• A semaphore is a data structure that is shared by several processes.
Semaphores are most often used to synchronize operations (to avoid
race conditions) when multiple processes access a common, non-
shareable resource.
There are two kinds of semaphores :
1. Binary semaphores : Control access to a single resource, taking the
value of 0(resource is in use) or 1 (resource is available).
2. Counting semaphores : Control access to multiple resources, thus
assuming a range of non-negative values.
·Semaphore is a nonnegative integer that is stored in the kernel. Access to
the semaphore is provided by a series of semaphore system calls.
05/02/2020 JBIET
Kernel support for semaphores
• UNIX System V.3 and V.4 contains semaphore table in the kernel address spacewhich
keeps track of all semaphore sets created in the system.
• ·Each entry in the semaphore table stores the following data for one semaphoreset :
1. A name that is an integer ID key assigned by the process which created theset.
2. The creator user ID and group ID.
3. The assigned owner user ID and group ID.
4. Read write access permission of the set for owner, group member, andothers.
5. The number of semaphores in the set.
6. A pointer to an array of semaphores.
7. The time when the last process changed one or more semaphore values.
8. The time when the last process changed the control data of the set.·
Semaphores in a set are referenced by array indices, such that the firstsemaphore in the set
has an index of zero ; the second semaphoreJBIET
05/02/2020
has an indexof 1; and so on.·
If a semaphore set is deleted, any processes that are blocked at that time due to semaphores are awakened by the kernel
using system calls and invoked are aborted and return a -1 failure status.

05/02/2020 JBIET
APIs for semaphores
• Unix system V semaphore APIs provide the following functions :
1.Create a semaphore set.
2.Open semaphores set and get a descriptor to reference the set.
3.Increase or decrease the integer values of one more semaphore in a set.
4.Query the values of one or more semaphore in a set.
5.Query or set control data of a semaphore set.
·The<sys/ipc.h> header defines a struct ipc_per mdata type, which stores
the user ID, group ID, creator user ID and group ID, assigned name key,
and read-write permission of a semaphore set.
05/02/2020 JBIET
05/02/2020 JBIET
File locking
File locking provides a very simple yet incredibly useful mechanism for
coordinating file accesses.

There are two types of locking mechanisms: mandatory and advisory. Mandatory
systems will actually prevent read()s and write()s to file.
advisory lock system, processes can still read and write from a file while it's
locked. Useless? Not quite,
since there is a way for a process to check for the existence of a lock before
a read or write. See, it's a kind of cooperative locking system. This is
easily sufficient for almost all cases where file locking is necessary

05/02/2020 JBIET
file locking with semaphores
• /* the program trying to write something to a file akr but it cannot write anything to the file
because the file is locked with semaphore at the time of writing. so there is no change in the
content of the file */

/home/ashok/~ cat akr


hi hello how are you?   /*original file */

/home/ashok/~ cc semlock.c
/home/ashok/~ ./a.out

/home/ashok/~ cat akr


hi hello how are you?   /* after modification also no change       
                         because file locked by the semaphore */

05/02/2020 JBIET
• http://cjuschools.blogspot.com/2016/07/file-locking-using-semaphores.html
TEXT BOOKS:
1. Unix System Programming using C++, T.Chan, PHI.
2. Unix Concepts and Applications, 4th Edition, Sumitabha Das, TMH, 2006.
3. Beginning Linux Programming, 4th Edition, N.Matthew, R.Stones, Wrox,
Wiley India Edition, rp-2008.
4. Unix Network Programming, W.R.Stevens, PHI.
5. Unix and Shell programming, B.A.Forouzan and R.F.Gilberg, Cengage
Learning.
REFERENCE BOOKS:
6. Advanced Programming in the Unix environment, 2nd Edition, W.R.Stevens,
Pearson Education.
7. System Programming with C and Unix, A.Hoover, Pearson.
8. Unix System Programming, Communication, Concurrency and Threads,
K.A.Robbins and S.Robbins, Pearson Education.
9. Unix shell Programming, S.G.Kochan and P.Wood, 3rd edition, Pearson
Education.
10. Shell Scripting, S.Parker, Wiley India Pvt. Ltd.
11. C Programming Language, Kernighan and Ritchie, PHI.

1. Linux System Programming, Robert Love, O’Reilly, SPD, rp-2007.

2. Unix for programmers and users, 3rd Edition, Graham Glass, King Ables, Pearson Education, 2003.

05/02/2020 JBIET

S-ar putea să vă placă și