Homework 2

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.

  1. 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.

  2. 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!

  3. If you rewrite the above code using printf(...) instead of write(1,...) to produce output, the output is different. Why?

  4. 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?