22C:116, Fall 1995
Due Friday Sept. 1, 1995, in class
Douglas W. Jones
Consider the following C program written to run under UNIX:
main()
{
int p1[2], p2[2], pid, cc, buf[1];
pipe(p1); pipe(p2); buf[0] = 0;
cc = write( p1[1], buf, 4 );
cc = write( 1, "pre-fork\n", 9 );
if ((pid = fork()) != 0) {
while (buf[0] < 4) {
cc = read( p2[0], buf, 4 );
cc = write( 1, "parent\n", 7 );
buf[0]++; cc = write( p1[1], buf, 4 );
} while (pid != wait(0)) { ; }
} else { /* child */
while (buf[0] < 4) {
cc = read( p1[0], buf, 4 );
cc = write( 1, "child\n", 6 );
buf[0]++; cc = write( p2[1], buf, 4 );
} exit(0);
} exit(0);
}
Note that you need not run this program, but it may be helpful to do so!
To understand this program, you may have to refer to the section 2 of
the UNIX programmer's reference manual, for example, as found at
the
the Ohio State archive or using the man 2 command on most
UNIX systems.
-
Describe, briefly, what this program does. Your description should focus
on the process structure of the program, the data flow between processes,
and how this leads to the output produced by this program.
Limit yourself to one paragraph.
-
Note that in some proposed high level languages for parallel programming,
the notation cobegin a; b; c coend is used to indicate the
execution of statements a, b and c in parallel, while
begin a; b; c end indicates that the statements are executed
in sequence.
Compared to this notation, the primitives provided by C and UNIX are
decidedly low-level. Translate the above C code to this high level
parallel programming notation!
-
If you rewrite the above code using printf(...) instead of
write(1,...) to produce output, the output is different. Why?
-
If you rewrite the above code using fdopen() to convert each
file descriptor to a stream, and then use the more common fprintf()
and fscanf() routines instead of using read() and
write on the two ends of the pipe, what change in behavior
would you expect, why, and how could you solve any of the resulting problems?