Introduction
:
#include
#include
#include
#include
int levels;
int sleep_val;
int R_MAX;
int L_MAX;
int get_ret(int ret)
{
if(ret%256!=0)
{
return(-1);
}
else
{
return(ret/256);
}
}
int TreeNode(int node_id,int level,int ppid)
{
int ans;
int pid;
int l_pid;
int r_pid;
int ret_pid;
int child_ret;
pid=getpid();
srand48(pid);
ans=(int)(drand48()150.0);
fprintf(stderr,”ID:%d\tPID:%d\tParent_PID:%d\tRand:(%d)\n”,node_id,pid,ppid,ans);
l_pid=-1;
r_pid=-1;
if(level==levels)
{
sleep(sleep_val);
}
else
{
l_pid=fork();
if(l_pid==0)
{
ans=TreeNode(node_id2,level+1,pid);
}
else
{
r_pid=fork();
if(r_pid==0)
{
ans=TreeNode(node_id2+1,level+1,pid);
}
else
{
ret_pid=wait(child_ret);
child_ret=get_ret(child_ret);
fprintf(stderr,”[PID:%d]\t”,pid);
if(ret_pid==r_pid)
{
fprintf(stderr,”RightChild:%d”,ret_pid);
if(node_id==1)
{
R_MAX=child_ret;
}
}
else
{
fprintf(stderr,”LeftChild:%d “,ret_pid);
if(node_id==1)
{
L_MAX=child_ret;
}
}
if(child_ret!=-1)
{
fprintf(stderr,”\tReturn:%d\tEXIT NORMALLY\n”,child_ret);
}
else
{
fprintf(stderr,”\tEXIT ABNORMALLY\n”);
}
if(child_ret>ans)
{
ans=child_ret;
}
ret_pid=wait(child_ret);
child_ret=get_ret(child_ret);
fprintf(stderr,”[PID:%d]\t”,pid);
if(ret_pid==r_pid)
{
fprintf(stderr,”RightChild:%d”,ret_pid);
if(node_id==1)
{
R_MAX=child_ret;
}
}
else
{
fprintf(stderr,”LeftChild:%d “,ret_pid);
if(node_id==1)
{
L_MAX=child_ret;
}
}
if(child_ret!=-1)
{
fprintf(stderr,”\tReturn:%d\tEXIT NORMALLY\n”,child_ret);
}
else
{
fprintf(stderr,”\tEXIT ABNORMALLY\n”);
}
if(child_ret>ans)
{
ans=child_ret;
}
if(node_id==1)
{
fprintf(stderr,”All sub processes exit\n”);
fprintf(stderr,”Left:%d\tRight:%d \tEntire:%d\n”,L_MAX,R_MAX,ans);
}
}
}
}
return(ans);
}
*Requirement
CPS 536 Homework 2
Deadline: In class, at class time, Thursday, 23 February, 2017
The goal is to become familiar with the basic ideas of processes in UNIX.
You are to write a program that creates a set of processes with a specified inter-
relationship (a full binary tree) and do some experiments and computation.
Your program will be invoked as
$ program-name levels sleep-val
where levels is the number of levels in the binary tree of processes created and sleep-val
is a positive integer between 1 and 30 (whose purpose is explained later). An illustration
is shown below where the number of levels is 3. Note that each process has an id (for our
identification) that is marked inside the node corresponding to the process; each process
also has its UNIX process id. Of the two children created, we will consider the first one
created as the left child while the other one as the right child. Note that if a process has id
k, then the id of its left child is 2k and that of the right child is 2k+1. Your program
(invoked from the shell) is to be carried out by the process whose id is 1.
Each process is supposed to generate a random nonnegative integer with value at most
150 using its process id as the seed value for the generator (look up drand48() and
srand48() and page 238 of Unix Systems Programming). You may consider this as the
data belonging to a process. The overall goal for you is to compute the largest of values
generated by processes in the left subtree (of the entire tree), the largest of the values
generated by processes in the right subtree (of the entire tree), and the largest of all the
values generated by the processes. A process is to communicate the result of any
computation it does to its parent by using it as the exit code in the call to exit().
Obviously, the parent should appropriately retrieve this information. Additional
information on the required behavior. of the processes is given below.
Required behavior. and output
At all times, make sure that those processes that can proceed concurrently do so.
You are to put each of processes at the leaf-level (and only those processes) to sleep for
sleep-val seconds before they exit.
All generated output should be sent to stderr. Use appropriate values for sleep-val so that
you can see the effect.
1
2 3
7
5 6
4
After each process comes into existence and has generated its random data, make it print
its integer id, its pid, and its parent’s pid, and the random number it generated.
Then, make each non-leaf process wait for its child(ren) to finish and retrieve the
information computed by the children.
Then, make the process report its own pid, that of the child that finished, the value
returned by the child, and report whether or not the child(ren) exited normally.
In the event that a child did not exit normally report what the reason for termination was.
When a process finishes abnormally, you may consider the largest value in the subtree
rooted at the process to be -1.
Finally, process with id=1 is to report the largest value in each of the two subtrees and
also the largest value in the entire tree.
(a) Run the program with number of levels being each of 2, 3. Turn in the sample
runs (output). Also, only for the case of levels = 3, turn in a schematic (as above)
of the processes along with their pids and values generated by them.
(b) Do as in (a) for number of levels = 4. But, this time kill each of processes with ids
5, 7, and 9 (from another shell, or by running your program in background). Turn
in the output.
If you want to capture (redirect) standard error to file stderr.out, then you would do the
following: $ program-name > stderr.out. Note that this will also redirect standard
output to the same file. Look up the manual pages for your shell if you need more
information.
What to turn in?
Hard copy of source code and sample runs for (a) and (b) above.
What to leave on the system?
Create a directory with the name hwk2 in your home directory. Leave all your files there.
Give the group r-x permissions for the directory hwk2 as well as for all the files your
leave there.