Jump to content

letstalkcode

Members
  • Posts

    1
  • Joined

  • Last visited

Everything posted by letstalkcode

  1. Inter Process Communication (IPC):- As we know, processes can be of two types:- Independent Processes - Processes that are not affected by the presence or execution of other processes. Co-operating Processes - Processes that are affected by the presence or execution of other processes. Most of the processes which we encounter are co-operating processes as processes that operate together achieve better modularity, computational speed, convenience, etc. Therefore, it is extremely crucial that various processes communicate with each other to keep a system running efficiently. The term IPC is an acronym for Inter-Process Communication. As is evident from the name itself, Inter-process communication is a mechanism that allows various processes to communicate with one another and synchronize their actions. Communication between the different processes could involve one process informing some other process that some event(s) has occurred. It might also mean that some process is transferring some kind of data to another process. The different processes communicating with each may be running on single or multiple computers, which are connected by a network. Hence, IPC is nothing but a set of programming interfaces that allow programmers to perform many activities among various program processes which are running simultaneously in an operating system. This provides for a particular program to handle a lot of user requests at the same time, thus, making the lives of programmers easy. Inter-Process Communication is, therefore, an extremely important topic of operating systems. It is often asked in the technical interviews of many big software companies (visit this site for more interview questions on operating systems) and therefore, students studying operating systems should definitely know in and out about Inter-Process Communication. Synchronization in Inter-Process Communication (IPC):- One of the most crucial parts of IPC is Synchronization. Synchronization is either provided by the inter-process control mechanism or taken care of by the communicating processes. A few methods that provide synchronization are listed below:− Semaphores: Semaphores are variables that control the access to a common resource(s), also known as the Critical Section, by different processes. There are two types of semaphores: counting semaphores and binary semaphores. Mutual Exclusion: Mutual exclusion allows only a single process thread to enter the critical section at a particular point time. Hence, mutual exclusion is extremely useful for synchronization as it prevents race conditions. Barrier: Barriers do not allow individual processes to proceed until all the processes have reached it. A number of parallel languages and collective routines impose barriers to synchronization. Spinlock: Spinlock is a kind of lock which processes try to acquire on various resources. The processes which try to acquire this lock will have to wait in a loop to check whether the lock is available or not. This is also known as busy waiting since the process, even though it is active, is not doing any useful operation. Different Approaches/Methods for Inter Process Communication (IPC):- Now that we understand what Inter Process Communication is, let us take a look at a few methods that are used for implementing the same:- Pipes:- One of the ways to achieve Inter Process Communication is through pipes. It is nothing but a mechanism using which the output of a single process is directed into the input of another process. Therefore, it provides a unidirectional flow of data between two related processes. Even though pipes can be accessed as ordinary files, the system usually manages pipes like FIFO queues. The pipe() system call is used to create a pipe file. A usual pipe file has an input end and an output end. We can read from the output end and write into a pipe from the input end. There is an array of two pointers present in a pipe descriptor. One pointer is for storing the input end of the pipe and the other pointer is for storing the output end of the pipe. Let us assume that two processes, Process One and Process Two, want to communicate with each other using pipes. In cases like these, it is crucial that the process which is writing closes its read end of the pipe, and the process which is reading closes its write end of the pipe. In other words, for successful communication between Process One and Process Two, the following criteria should be satisfied:- The first Process should keep its write end of the pipe open and the read end closed. Process Two should keep its read end open and close its write end. On successful creation, a pipe is given a fixed size in bytes. If the pipe is not full and some process wants to write into the pipe, the write request is executed spontaneously. However, if the pipe is full when the process wants to write into the pipe, it is blocked until the state of the pipe changes. The same things happen if a reading process tries to read more bytes than what is currently in the pipe and gets blocked. On the other hand, the reading process is executed without any issues if it tries to read-only sufficient bytes that are there in the pipe. Only a single process can access a pipe at any particular point in time. Disadvantages of Using Pipes for Inter Process Communication:- Pipes are unidirectional, hence not very useful. Broadcasting is not supported by pipes, that is, a single process cannot send messages to multiple processes at a single point in time. A bit of plumbing, that is, the closing of ends, is required in order to create a properly directed pipe. Named Pipes or FIFOs:- Another technique or method used for inter-process communication is named pipes or FIFOs. It is nothing but an extension of the traditional pipe concept of the Unix operating system. Usually, a traditional pipe is not named and exists only as long as the process lasts. However, a FIFO or a named pipe can last till the time the system is up even if the process is dead. Named pipes can be deleted if no longer used. Generally, named pipes appear in the form of files and usually, processes attach to these pipes for IPC (inter-process communication). Using FIFO files of the local storage, two or more processes can communicate with one another by reading from or writing to this file. In order to enter a FIFO special file into the filesystem, we need to call the special system call mkfifo() in the C language. Once the FIFO file has been created, any process can open it for reading or writing purposes just like the way ordinary files work. However, the named pipe needs to be open at both ends at the same time before one can proceed to do any kind of input or output operations on it. We can create a FIFO file using the mkfifo() functions as shown in the below-given syntax :- int mkfifo(const char *pathname, mode_t mode); Explanation: The function mkfifo() creates a FIFO special file with the name pathname. In the syntax, “mode” lists down the permissions of the FIFO. Now let us take a look at a couple of C programs to understand how named pipes work:- Code- 1 /* A program in the C language to illustrate one side of the FIFO pipe This end of the pipe writes first and then reads */ //including all the necessary header files #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <string.h> #include <unistd.h> #include <fcntl.h> //start of the main function of the C program int main() { // FIFO file path variable char * myFifo = "/tmp/myFifo"; /* This line creates the named pipe(FIFO) using the syntax : mkfifo(<pathname>, <permission>)*/ mkfifo(myFifo, 0666); //file descriptor variable int fileDescriptor; char array1[100], array2[100]; while (1) { // Opening FIFO for writing only fileDescriptor = open(myFifo, O_WRONLY); /* Taking an input array2 string from the user of maximum length 100.*/ fgets(array2, 100, stdin); // Writing the given input array2 string on the FIFO write(fileDescriptor, array2, strlen(array2)+1); //closing FIFO close(fileDescriptor); // Opening FIFO for Reading only fileDescriptor = open(myFifo, O_RDONLY); // Reading from FIFO read(fileDescriptor, array1, sizeof(array1)); // Printing the message which has been read printf("User2 says: %s\n", array1); close(fileDescriptor); } return 0; } //end of main function Code 2:- /* A program in the C language to illustrate one side of the FIFO pipe This end of the pipe reads first and then writes */ //including all the necessary header files #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <string.h> #include <unistd.h> #include <fcntl.h> //start of the main function of the C program int main() { // FIFO file path variable char * myFifo = "/tmp/myFifo"; /* This line creates the named pipe(FIFO) using the syntax : mkfifo(<pathname>, <permission>)*/ mkfifo(myFifo, 0666); //file descriptor variable int fileDescriptor2; char string1[100], string2[100]; while (1) { // Firstly, this end opens in read only mode and reads fileDescriptor2 = open(myFifo,O_RDONLY); read(fileDescriptor2, string1, 100); // Printing the read string printf("User1 says: %s\n", string1); //closing the fifo close(fileDescriptor2); /* Opening FIFO in write mode and writing the string taken as input from the user.*/ fileDescriptor2 = open(myFifo,O_WRONLY); fgets(string2, 100, stdin); write(fileDescriptor2, string2, strlen(string2)+1); close(fileDescriptor2); } return 0; } Explanation: In the above-given code snippets, the first program writes first into the pipe and then reads from it while the second code reads first from the pipe and then writes into it. This process continues until one of the processes terminates. Shared Memory:- In this method of inter process communication, two or more processes communicate with each other by sharing some common memory, where changes made by a particular process can be viewed by all other processes. The issue with other methods for IPC like pipes, fifos, message queues, etc is that for two processes to exchange data, the data needs to go via a kernel. The following four steps occur in the above mentioned IPC methods :- Firstly, the server reads from the file meant for input. Secondly, the server writes this information in a message using a fifo, pipe or message queue. After that, the client reads the information from the IPC channel, and it requires the data to be copied to the client’s buffer from the kernel’s IPC buffer. At last, the data is copied from the client’s buffer. As we can see, in total, four copies of data are required (two for read and two for write). IPC via shared memory gives us a better way by letting multiple processes share a common memory segment. When shared memory is used, the data is copied twice only – once from the input file into the shared memory and secondly, from the shared memory to the output file. Now let us take a look at the code snippets for the Writer and the Reader Processes using Shared Memory for IPC :- Code for Writer Process: /* A program in the C language to illustrate the Writer process using Shared Memory for IPC*/ //including all the necessary header files #include <sys/shm.h> #include <stdio.h> #include <iostream> #include <sys/ipc.h> using namespace std; //start of the main function of the C program int main() { // The ftok() function is used to generate a unique key key_t key = ftok("shmfile",65); /* The shmget() function returns an identifier for the shared memory segment in shmid*/ int shmid = shmget(key,1024,0666|IPC_CREAT); /* In order to use the shared memory segment, the shmat() function is used to attach to the shared memory*/ char *s = (char*) shmat(shmid,(void*)0,0); cout << "Data for Writing: "; gets(s); printf("Data that has been written in memory is: %s\n",s); //detaching our program from the shared memory shmdt(s); return 0; } //end of main function Code for Reader Process:- /* A program in the C language to illustrate the Reader process using Shared Memory for IPC*/ //including all the necessary header files #include <sys/shm.h> #include <stdio.h> #include <iostream> #include <sys/ipc.h> using namespace std; //start of the main function of the C program int main() { // The ftok() function is used to generate a unique key key_t key = ftok("shmfile",65); /* The shmget() function returns an identifier for the shared memory segment in shmid*/ int shmid = shmget(key,1024,0666|IPC_CREAT); /* In order to use the shared memory segment, the shmat() function is used to attach to the shared memory*/ char *s2 = (char*) shmat(shmid,(void*)0,0); printf("Data that has been read from the memory is: %s\n",s2); //detaching our program from the shared memory shmdt(s2); // destroying the shared memory using the function shmctl() shmctl(shmid,IPC_RMID,NULL); return 0; } // end of main function Message Passing:- Message passing is one of the methods for Inter Process Communication that allows multiple processes to read data and write data to the message queue. In this method, the processes need not be connected to each other. In message passing, messages are stored inside the queue until their recipient retrieves them. Let us take a look at some of the advantages of the Message Passing method:- The message passing method is a lot easier to implement than the shared memory method. Building parallel hardware using the message passing model is way easier as it is very tolerant of higher communication latencies. However, the message passing method is a slower communication method than the shared memory method as the connection setup takes a little time. Message Queue:- Last, but not least, one of the methods for IPC is Message Queues. Message queues are linked lists of messages stored within the kernel. They can be identified by a message queue identifier. Using the function msgget(), a new queue can be created or an existing queue can be opened. In message queues, the function msgsnd() can be used for adding new messages to the end of the queue. All the messages have a positive long integer type field, a non-negative length, and the actual data bytes (corresponding to the length). All of this information is specified to the function msgsnd() when the message is added to a queue. In order to fetch messages from a queue, the function msgrcv() is used. We don’t have to fetch the messages in a first in first out (FIFO) order. Instead, the messages can be fetched based on their type field. In message queues IPC method, the sending process places a message (through some Operating System message passing module) onto a queue. This can be read by some other process. Each message is given an ID or a type so that the processes can select the appropriate message. In order to gain access to the queue, different processes must share a common key. Now let us take a look at the code snippets for the Writer and the Reader Processes using Message Queue for IPC :- Code for Writer Process: // Program in the C language to illustrate the Writer Process using a Message Queue //including all the necessary header files #include <stdio.h> #include <sys/msg.h> #include <sys/ipc.h> #define MAX 100 // structure used for a message queue struct messageBuffer { long messageType; char messageText[150]; } message; //start of main function of the C program int main() { // The function ftok() is used to generate a unique key key_t key = ftok("progfile", 65); /* The function msgget() is used to create a message queue and returns an identifier */ int msgid = msgget(key, 0666 | IPC_CREAT); message.messageType = 1; printf("The data written is : "); fgets(message.messageText,MAX,stdin); // The function msgsnd() is used to send message msgsnd(msgid, &message, sizeof(message), 0); // displaying the message printf("Data that has been sent is : %s \n", message.messageText); return 0; } //end of main function Code for Reader Process:- // Program in the C language to illustrate the Reader Process using a Message Queue //including all the necessary header files #include <stdio.h> #include <sys/msg.h> #include <sys/ipc.h> #define MAX 100 // structure used for a message queue struct messageBuffer { long messageType; char messageText[150]; } message; //start of main function of the C program int main() { // The function ftok() is used to generate a unique key key_t key = ftok("progfile", 65); /*The function msgget() is used to create a message queue and returns an identifier*/ int msgid = msgget(key, 0666 | IPC_CREAT); /*The function msgrcv() is used to receive messages in message queue*/ msgrcv(msgid, &message, sizeof(message), 1, 0); // displaying the message printf("Data that has been received is : %s \n",message.messageText); // The function msgctl() is used to destroy the message queue msgctl(msgid, IPC_RMID, NULL); return 0; } //end of main function Conclusion:- Let us now take a look at a few advantages of Inter Process Communication:- Inter Process Communication is used to speed up modularity. IPC is computational and has Privilege separation IPC provides convenience as processes can communicate with each other and carry out difficult tasks with ease. Hence, as we can see, Inter Process Communication is an extremely important topic as far as Operating Systems are concerned. Therefore any budding student studying operating systems should definitely learn about Inter Process Communication and we hope we have been able to make the topic extremely clear for our readers.
×
×
  • Create New...