CS360 Final Exam - May 9, 2011 - James S. Plank

Answer all questions on the answer sheet

Question 1

Write a program pmain.c that creates two processes, and does not return until both processes have completed. The first process is defined as follows:

The second process is defined as follows:

In other words, the processes look as follows:

Both processes should have no other open file descriptors. You may assume that there's a procedure error() that calls perror() and exits. Makes life easier.

Question 2

Your colleague Skippy has written a program called experiment that runs for some fairly random period of time, appends its output to a log file, and exits. Skippy wants a program that will maintain a certain number of experiment processes running on his machine at all times, and he wants to be able to change that number at will. However, Skippy got a D in CS360 and doesn't know how to do it. Fortunately, Skippy does have access to lots of grant money, so he'll shovel $500 your way to write the program. Easy money, since I'm going to make you write it on your exam. Twice. Kind of.

Your job is to write the program skipex. It is going to use pthreads to solve Skippy's problem. At all times, it is going to make sure that n experiment processes are running. It only needs two threads. One reads from standard input and one waits for experiment processes to die. The one that reads from standard input simply reads integers -- that is how n is set and changed. You can use scanf() for this one if you want -- nothing fancy. Have skipex die if the scanf() call fails or if the user enters an integer &le 0. When you die, don't worry about the experiment processes that are currently running.

Your program will start with n equal to zero. When n is first set, you create n experiment processes (this is a very simple fork()/execl()). Your second thread monitors when processes die and replaces them. When the user increases n, you create more processes. When the user decreases n, your second thread will not replace processes when they die, until there are only n running.

Make sure you pay attention to race conditions, and remember that if a process has no children, wait() will return instantly.


Question 3

Now, suppose Skippy does not have access to a lot of grant money, and instead is running off a 1990 Intel 386 processor that can only load Linus Torvalds' original beta version of Linux that doesn't have pthreads. You are in gambling debt to Skippy, so you have to write skipex for free.

You can do this with fork()/exec()/pipe()/select()/wait(). You do not have to touch experiment. Explain to me how you do this. I am not requiring code here, although if you want to write skipex.c, feel free to. I want your explanation to describe exactly what you are doing -- when you make each system call, and perhaps a picture of the state when n equals, say, three.

Oh, and you must use wait(), not waitpid(), wait3() or any of that other garbage. No polling allowed either.

Hint: When the write end of a pipe goes away, read returns zero.


Question 4

Behold the program mq.c:

#include <stdio.h>
#include <stdlib.h>

main()
{
  int *ip, *i2, i;
  char *s;

  ip = (int *) malloc(sizeof(int)*4);
  for (i = 0; i < 4; i++) ip[i] = 5+i;
  printf("0x%lx\n", (unsigned long) ip);
  s = (char *) malloc(sizeof(char)*61);
  i2 = (int *) malloc(sizeof(int)*3);
  for (i = 0; i < 3; i++) i2[i] = 10+i;
  free(s);
  s = (char *) malloc(sizeof(char)*9);
  strcpy(s, "ABCDEFGH");
  sleep(10000);
}

Suppose the program prints 0x6100 as its first line. At the point where the program sleeps, I would like you to tell me the contents of every byte of the heap that you know about. You may make the following assumptions:

To be specific -- give me a table that specifies addresses, identities, values. Use the answer sheet -- however, I'll fill in one entry for you:

Addresses IdentityValue(s)
0x6100 to 0x6103ip[0]5