Fill This Form To Receive Instant Help
Homework answers / question archive / Computer Operating System Experiment Laboratory 3 Inter-Process Communication Objective: In computer science, Inter-process communication (IPC) is a mechanism which allows processes to communicate with each other and synchronize their actions
Computer Operating System Experiment
Laboratory 3
Inter-Process Communication
Objective:
In computer science, Inter-process communication (IPC) is a mechanism which allows processes to communicate with each other and synchronize their actions. IPC provides a mechanism to allow the processes to manage shared data. The objective of this lab is to help you internalize a couple of important facts about IPC in Linux.
Including:
VirtualBox with Ubuntu Linux
Program and answer all the questions in this lab sheet.
A process is a program in execution, and each process has its own address space, which comprises the memory locations that the process is allowed to access. An independent process is not affected by the execution of other processes while a co-operating process can be affected by other executing processes. Though one can think that those processes, which are running independently, will execute very efficiently, in reality, there are many situations when co-operative nature can be utilized for increasing computational speed, convenience and modularity. Inter process communication (IPC) is a mechanism which allows processes to communicate with each other and synchronize their actions.
Cooperating processes require an inter-process communication (IPC) mechanism that will allow them to exchange data and information. There are two fundamental models of inter-process communication: shared memory and message passing. In the shared-memory model, a region of memory that is shared by cooperating processes is established. Processes can then exchange information by reading and writing data to the shared region. In the message-passing model, communication takes place by means of messages exchanged between the cooperating processes such as pipes, message queue, and sockets.
Inter-process communication using shared memory requires communicating processes to establish a region of shared memory. Typically, a shared-memory region resides in the address space of the process creating the shared-memory segment. Other processes that wish to communicate using this shared-memory segment must attach it to their address space.
These are steps for shared memory communication:
POSIX provides five entry points to create, map, synchronize, and undo shared memory segments:
|
A program shown in text book (page 133) use the producer-consumer model in implementing shared memory. The producer establishes a shared memory object and writes to shared memory, and the consumer reads from shared memory.
Requirements:
You need to write codes that implements a parent and child process that communicates via a shared memory object.
Shared Memory Objects and Linux Kernels
On Linux, all shared memory objects can be found in /dev/shm. You may list them with ls -l /dev/shm. You may also remove a shared memory object with rm /dev/shm/[name]. This is handy when you are debugging your program.
Questions:
1. On Linux, all shared memory objects can be found in /dev/shm. Can you find the shared memory objects that you created?
Ordinary pipes allow two processes to communicate in standard producer– consumer fashion: the producer writes to one end of the pipe (the write-end) and the consumer reads from the other end (the read-end). As a result, ordinary pipes are unidirectional, allowing only one-way communication. If two-way communication is required, two pipes must be used, with each pipe sending data in a different direction. We next illustrate constructing ordinary pipes on Linux systems. In the example, one process writes the message Greetings to the pipe, while the other process reads this message from the pipe. An ordinary pipe cannot be accessed from outside the process that created it. Typically, a parent process creates a pipe and uses it to communicate with a child process that it creates via fork().
On Linux systems, ordinary pipes are constructed using the function
pipe(int fd[ ])
This function creates a pipe that is accessed through the int fd[] file descriptors: fd[0] is the read-end of the pipe, and fd[1] is the write-end.
In order to send structured data through a pipe, you have to serialize it to push it from the sending to receiving process as a stream of bytes. For instance, imagine you are sending a struct type: you have to turn the struct into a sequence of bytes in order to send them over the pipe.
When you send two different instances of serialized data structures over a serial channel such as a Linux pipe, you have to be able to distinguish where one datum ends and the next one begins. What you use as the “marker” or “sentinel value” that distinguishes the two instances is up to you to define.
Copy the pipes-test.c program from the text book (Page 143) to another file named pipes.c. Now, modify your new program so that the parent process read to the pipe content from child process when child process executed commands.
The program first creates a pipe, and then creates a child process of the current process through fork(). Then each process closes the file descriptors that are not needed for the read and write pipes. The child process executes the "ls -a" command under the current path, and writes the command execution output to the pipe by copying the pipe write descriptor fd[1] to standard output; the parent process reads the pipe data and displays it through fd[0] .
Every process in Linux is provided with three standard file descriptor including standard input, output and error files. By default:
A file descriptor is simply a number that refers to an open file. By default, file descriptor 0 (zero) refers to the standard input & often abbreviated as stdin. File descriptor 1 refers to standard output (stdout) and file descriptor 2 refers to standard error (stderr).
You can use dup(2) function to duplicate a file descriptor with the pipe write descriptor fd[1] by using function dup2 in order to relocate the standard output.
// dup2() makes newfd be the copy of oldfd, closing newfd first if necessary int dup2(int oldfd, int newfd); |
Copy your pipes-test.c program to another file named upper.c. Modify your program so that it defines two pipes: one for communication from parent to child and another for communication from child to parent. Make sure to close the correct ends of each pipe. Ultimately, your goal is to have two pipes, one in each direction, so that you have bi-directional communication between the two processes. It helps a lot to use names for the pipes file descriptors that indicate their direction. For instance: p-to-c and c-to-p tell us the processes that the pipes interconnect and the direction of the flow of information.
This new version of the program must behave as follows.
Make sure to reason carefully about when the write ends of the two pipes should be closed, so that your processes can terminate their loops gracefully and reach their termination state when appropriate. Also, make sure to use the wrappers defined previously (Fork, Pipe, Read, and Write).
Questions:
We used one pipe for one-way communication and two pipes for bi-directional communication. We can use single named pipe that can be used for two-way communication (communication between the server and the client, plus the client and the server at the same time) as Named Pipe supports bi-directional communication. Named pipes provide a much more powerful communication tool. Communication can be bidirectional, and no parent–child relationship is required.
A named pipe, however, can last as long as the system is up, beyond the life of the process. It can be deleted if no longer used. Usually a named pipe appears as a file and generally processes attach to it for inter-process communication. A FIFO file is a special kind of file on the local storage which allows two or more processes to communicate with each other by reading/writing to/from this file.
A FIFO special file is entered into the filesystem by calling mkfifo() in C. Once we have created a FIFO special file in this way, any process can open it for reading or writing, in the same way as an ordinary file. However, it has to be open at both ends simultaneously before you can proceed to do any input or output operations on it.
The following steps outline how to use a named pipe from Linux programs:
Creating a FIFO file: In order to create a FIFO file, a function calls i.e. mkfifo is used.
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);
mkfifo() makes a FIFO special file with name pathname. mode specifies the FIFO's permissions. Pathname specifies the name of the new FIFO. mode specifies which access modes the FIFO has when it is created. Refer to the documentation for stat() for a discussion of access mode flags. You can use 0666 (read and write allowed for everyone) |
Requriments:
You need to write two programmers which follow rules below.
Step 1: Create two processes, one is client and another one is server.
Step 2: Server process performs the following:
Step 3: Client process performs the following:
Questions:
Please download the answer file using this link
https://drive.google.com/file/d/1hvd6MkhyyrruFz8hmemEfGhdsZz1vXWu/view?usp=sharing