Question
This program demonstrates how IPC can be used to communicate data between two processes. The program will do the following when it runs: 1. The
This program demonstrates how IPC can be used to communicate data between two processes.
The program will do the following when it runs:
1. The user is asked to enter the number of bytes of data that should be transferred. This
value is passed to the generate_data function to create a data string of that many bytes
to be transferred between the parent and child processes.
2. A function named pipe_xfer is called to create a child process and use a named pipe to
transfer the data string from the parent process to the child. After the transfer is
complete, the child process will verify that it received the data correctly and display the
result to the terminal.
3. After pipe_xfer is finished, a function named msg_xfer is called to create a child process
and use message queues to transfer the data string from the parent process to the child.
After the transfer is complete, the child process will verify that it received the data
correctly and display the result to the terminal.
The included main.cpp file contains specific instructions about what to implement.
.
Sample Output
The program should produce output like this, when launched from a terminal.
Enter number of bytes: 5000
[Parent] Created string of 5000 bytes.
[Child] Named pipe transfer is correct.
[Child] Message queue transfer is correct.
Press ENTER to continue...
.
Helpful Commands
ipcs and ipcrm
make
.
use this template
#include
#include
#include
#include
#include
#include
#include
// message queues
#include
// named pipes
#include
#include
#include
#include
using namespace std;
// Generates a string of ASCII characters for use as data
// Takes in an integer that specifies how many bytes/chars the string contains
char * generate_data (int numberOfBytes)
{
char * result = new char[numberOfBytes];
char value = 65;
for (int i = 0; i < numberOfBytes; i++)
{
result[i] = value++;
if (value > 126)
value = 65;
}
result[numberOfBytes-1] = '\0';
return result;
}
// Use this message format for sending data
// through the message queues.
struct DataMessage
{
long priority;
char data[10];
};
// Global values that define the data
// to be transferred. The child processes
// will have access to this information.
char * data_string;
int size = 0;
// Sends data using a message queue.
void msg_parent (int qid) {
/* (10 points)
TODO: Send the data_string to the child process using
the message queue.
*/
}
// Receives data over a message queue.
void msg_child (int qid) {
char * recv_data = new char[size];
/* (10 points)
TODO: Receive the data from the parent process
using message queues. Store the data in
recv_data. Hint: The size of the string to be
received is known to the child through the size
global variable.
*/
// Verifies the data transferred correctly
if (strncmp (data_string, recv_data, size) == 0) {
printf ("[Child] Message queue transfer is correct. ");
} else {
printf ("[Child] Message queue transfer is incorrect. ");
}
}
// Creates a child process and has the parent process
// send data to the child process through a message queue.
void msg_xfer () {
/* (5 points)
TODO: Create a message queue with key of 1234.
After the fork, both the child and the parent
will have access to this queue.
*/
int qid = 0;
// Creates a child process and initates the transfer of data
// from the parent to the child.
pid_t pid = fork ();
if (pid > 0) {
msg_parent (qid);
wait (NULL);
/* (5 points)
TODO: Destroy the message queue that you created.
*/
} else if (pid == 0) {
msg_child (qid);
// Exit child process
exit (0);
} else {
cout << "Error creating child process. ";
}
}
// Sends data through a named pipe
void pipe_parent () {
/* (10 points)
TODO: Open the named pipe as a producer and send the contents
of data_string to the child process to be consumed. Close
the pipe when the transfer is complete.
*/
}
// Receives data from a named pipe
void pipe_child () {
char * recv_data = new char[size];
/* (10 points)
TODO: Open the named pipe as a consumer and receive the data
being sent from the parent process into recv_data. Close
the pipe when the transfer is complete.
Hint: The size of the string to be
received is known to the child through the size
global variable.
*/
// Verifies that the data was recieved correctly.
if (strncmp (data_string, recv_data, size) == 0) {
printf ("[Child] Named pipe transfer is correct. ");
} else {
printf ("[Child] Named pipe transfer is incorrect. ");
}
delete[] recv_data;
}
// Creates a child process and has the parent process
// send data to the child process through a named pipe.
void pipe_xfer () {
/* (5 points)
TODO: Create a named pipe called "CPSC351-PIPE."
*/
// Creates a child process and initates the transfer of data
// from the parent to the child.
pid_t pid = fork ();
if (pid > 0) {
pipe_parent ();
wait (NULL);
/* (5 points)
TODO: Delete the named pipe called "CPSC351-PIPE."
*/
} else if (pid == 0) {
pipe_child ();
// Exit child process
exit (0);
} else {
cout << "Error creating child process. ";
}
}
int main(int argc, char **argv)
{
size = 1024;
cout << "Enter number of bytes: ";
cin >> size;
data_string = generate_data(size);
printf("[Parent] Created string of %d bytes. ", size);
pipe_xfer ();
msg_xfer ();
delete data_string;
return 0;
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started