Cmput 379 Lab Exercise #2

For the period 19-25 January, 2001

Objective

Write a C-program to explore the use of: Report to your TA by email at the end of the lab period, outlining what you learnt from this exercise.

Filenames

Hold your source code in a single file called ParentChild.c and your compiled executable code in ParentChild. The stderr output can appear in a file called ParentChild.err
It was inferred previously that if both the parent and the child write to the same file attached to stderr, data may be lost.  One way around this problem is to put a timestamp on each message and send them to different files for later merging.  Probably there are more elegant solutions using freopen().  As a general rule it is probably worth avoiding the parent and child writing to the same file.

Program Review (previous week's work)

During the first week you might have written a small program along the following lines:

The parent creates a pipe and forks off a child process.  The parent then enters an infinite loop reading data lines until an EOF occurs.  Each line is written into the pipe (using the write() system call), and is read by the child.  One problem both the parent and child face is that they do not know how long the line is going to be.  Addressing this issue was one objective of Lab. 1.

Issues that arise are how to recognize an end-of-file on a pipe and how to pass an end-of-file down a pipe.

The more interesting model might be: The parent is in an infinite loop reading lines of data until an EOF occurs.  Before each line is read a child process is spawned and the data passed to it via a pipe.  The child reads the line of data from the pipe, outputs it to stdout and terminates.

This is a kind of Client/Server model, where the parent (client) sends each line of data to a server (a new server thread) as a transaction for processing.  One might then be able to have multiple concurrent Child processes.

Issues that could arise:
when executed as a command line of the form

ParentChild
there is no problem, but  when executed as:
ParentChild <infile >outfile
There may be a problem if infile is large (has very long or varied-length lines).  Children will be created in rapid succession and, depending on how the i/o is done and when the context switches occur, a later initiated child process may output  some of its characters before  an earlier process has finished. There should not be any lost data.  Students should demonstrate any program with execution anomalies to their TA.

Program Guidelines (this week's work)

Re-implement last week's program, but use the client/server model of computation--one new child for every new line of data.  However, now the Child Process directs its stdout channel to a new pipe that returns the output to the parent for display on the parent's stdout.  The Child should do some simple manipulation on the data stream (e.g., force all alphabetic characters into upper case), so that it is clear that the line has been processed by the child.
Note, for this arrangement to be consistent with the Unix standard of simplicity (a pipe is a one-way communication device), a new (additional) pipe is essential for the return traffic. Note that under Solaris a pipe is a two-way device, while this is not the case under Linux. For portability, therefore, you will want to treat the pipe as a one-way device, and close off the unused portions appropriately.

Be careful not to have the children spawn children of their own, because this can result in an infinite creation of processes.  The problem can arise easily if the child does not exit but simply continues to execute the balance of the "parent" code.

Program Execution

It should be possible to invoke your program in the following ways:
ParentChild
<infile ParentChild >outfile
cat infile | ParentChild >outfile

Questions

  1. Are both Ctrl-D and Ctrl-C equally effective in terminating the application?
  2. What other ways are there of terminating processes?

Copyright © Department of Computing Science.
All rights reserved.
Last update: