CSCI 480 Assignment 2 — Process Communication


Category: You will Instantly receive a download link for .zip solution file upon Payment


5/5 - (3 votes)

This assignment involves using the LINUX system function pipe() as well as fork().

We will have three processes which communicate with each other using pipes. The three processes will be parent, child and grandchild.
Their communication will run in a ring like this:

Pipe A Pipe B
—> Parent ———-> Child ———-> Grandchild —>
| |
<--------------<--------------<-------------<----------- Pipe C Each process will read a number (in character format) from a pipe, convert it to an integer, do a bit of arithmetic, convert the result to character format (a string) and write it into the other pipe for the next process to read. Write a program on the turing system using C or C++ to implement this. The following description assumes that the strings involved are C-style strings (character arrays ending in \0). It should also be possible to do this using the C++ string class. If you wish to do so, see the notes below. --------------------------------------------------------------------- Main program 1. Declare three pipe variables (which I will call Pipe A, Pipe B and Pipe C). Each is an array of two integers. 2. Call the pipe() function once for each pipe variable. 3. If any use of pipe() fails (returning -1), print an error message (such as "pipe #1 error") and exit with a status of -5. 4. Call the fork() function twice to create the three processes: once in the parent and then again in the child. Do not create more than 3 processes. If fork() fails (returning -1), print an error message (such as "fork #2 error") and exit with a status of -5. 5. At this point we have three processes, parent, child and grandchild. Each of these should call a function to do the rest of its work. We can call these PWork() for the parent, CWork() for the child and GWork() for the grandchild. Before calling its function, each process should close the appropriate ends of the pipes it will use. (The parent reads from Pipe C and writes to Pipe A, so it should close the write end of Pipe C and the read end of Pipe A, and likewise for the other two.) When the functions end, the processes should close the remaining ends of the pipes and then exit with a status of 0. (The child should use wait() to wait until the grandchild terminates, and the parent should do the same for the child.) 6. Return a value of 0. (This is not really needed as we are using exit(), but it's a good habit.) --------------------------------------------------------------------- What do the functions do? 1. Declare two char arrays, Buffer and Value, each of size at least 10. Initialize Value to "1". Also declare an integer M with the initial value 1. In PWork() (but not in the other two), start by writing Value to the appropriate pipe. Print a message announcing this is the parent and providing the value of Value. (This is the principal difference between PWork() and the others: it starts the processing.) 2. In a loop, while M is no more than 99999999 (that is eight 9s), do the following: (a) Read one byte at a time from the appropriate pipe and store them in Value, building a string. Stop when you find '\0'. (b) Make sure Value ends properly as a string with '\0'. (c) Convert the string Value to an integer value in M. (d) Compute M = 4 * M + 3. (e) Convert M to a string in Buffer. (f) Write Buffer to the appropriate pipe. Print a message identifying who is printing (parent, child or grandchild) and providing the value of Value. --------------------------------------------------------------------- Option to use the C++ string class If you prefer to use the C++ string class, you will need to make a few changes to the functions: --- The variables Buffer and Value should be declared as strings. --- When you write a string to the pipe, the other process must be able to identify the end of the transmission. Therefore, use some character such as '@' as a delimiter. --- When a process reads a string from the pipe, it should read one byte at a time until it finds the delimiter. Do not print the delimiter or use it in converting a string to an integer. --------------------------------------------------------------------- Notes You should decide for yourself what arguments you need to pass to these functions. As the three functions are so similar, you may be able to improve the design by making the overlapping part into a separate function. You may want to read up on read() and write() and how to convert a string to an integer. Please print your output without buffering. As in Assignment 1, the simplest way to do this is to use stderr instead of stdout. Your program should use reasonable variable names and should be appropriately indented and well documented. You can find style guidelines on the web sites of the CSCI 240 and 241 courses. You should have a makefile. The name of the executable file should be "Assign2". When you are done, you need to submit your work on Blackboard. As in Assignment 1, you should create a tar file containing the two files involved: the program file and the makefile. To do this, you need the "tar" utility. Do the following (replacing "Znumber" with your own Z-ID): (a) Create a subdirectory named Znumber_A2_dir. (b) Copy the three files into it. (c) In the parent directory of Znumber_A2_dir, use this command: tar -cvf Znumber_A2.tar Znumber_A2_dir Use an FTP program to retrieve the tar file and then submit it on Blackboard. The TA will move it to turing, extract the files and run your makefile, as in: tar -xvf Znumber_A2.tar cd Znumber_A2_dir make Assign2 If your makefile does not run or your program does not compile and run, you will receive no credit. --------------------------------------------------------------------- Sample Output This is an example of the output. If you run your program several time, you may find you have some of the lines in a different order. Parent: Value = 1 Child: Value = 7 Grandchild: Value = 31 Parent: Value = 127 Child: Value = 511 Grandchild: Value = 2047 Parent: Value = 8191 Child: Value = 32767 Grandchild: Value = 131071 Parent: Value = 524287 Child: Value = 2097151 Grandchild: Value = 8388607 Parent: Value = 33554431 Child: Value = 134217727 Grandchild: Value = 536870911 Parent: Value = 2147483647