Question
UNIX PROJECT: Please post output! This project will be written in C where there will be two executable files. The first executable file, called ex1,
UNIX PROJECT: Please post output!
This project will be written in C where there will be two executable files.
The first executable file, called ex1, will be in charge of launching a specific number of child processes at various times using fork() followed by an exec(). ex1 will keep track of how many children have finished executing and terminate itself only when all of its children have finished.
When ex1 is ran, it should take in several command line options.
- -h, to describe how it should be run. The -h option should indicate the default running environment of ex1.
- -n x option to indicate the maximum total of child processes it will ever create.
- -s will indicate how many children should be allowed to exist in the system at the same time
- The last two options are for input and output files, -i and -o respectively
These files are used only by ex1 and will have defaults of in.txt and out.txt.
The default will have a maximum of 4 child processes and 2 live children at any given time.
Example: if called with -n 10 -s 5 , ex1 would want to fork/exec 5 child processes but then not create any more until one of them has terminated. Once one child terminates, it would create another. It will continue this until it had created a total of 10. Then it would wait until all of them have terminated.
The executable, ex1, will also be responsible to create shared memory to store 2 integers and then initializing those integers to zero. This shared memory will be accessible to the children.
Note: This shared memory will act as a clock:
- one integer represents seconds
- the second integer represents nanoseconds
ex1 will be responsible for advancing this clock by incrementing it at various times:
Note: child processes do not ever increment the clock, they only look at it.
Implementation: When ex1 starts, it should parse command line options and then allocate shared memory. It will open the input file. The input file starts with a number, which is our default increment value for the clock (in nanoseconds).
The rest of the file should consist of rows with two numbers, as the following example:
20000
0 64867 375891
0 563620 5000000
0 2758375 375620
1 30000 35000
...
This file should be read as indicating that the first child should be launched no earlier than at time 0 seconds and 64867 nanoseconds in our clock.
The third column is the duration which we will discuss later.
The second child should be launched no earlier than at time 0 seconds and 563620 and so forth.
The main program will contain a loop, in which the process starts by incrementing the clock by the constant specified in the file. It should then check if the current simulated time is high enough that it should launch a child process.
It should fork and then exec the child, passing it as a command line argument the duration (third number in the file).
Note that it should only launch this child process if it does not violate the -n and -s command line options.
If we already have too many child processes launched, then it should just not launch a child process and do another iteration of the loop. When it launches a child process, it should write in the output file the simulated time it launched the child process, the childs pid, and the duration it passed to the child. During each iteration of the loop, it should also check to see if any child processes have terminated. If any child has terminated, it should write to the output file the pid of the terminated process and the simulated time of its termination.
Termination Criteria:
- if all the children have finished and the input file does not specify needing to launch more, the parent/main process should free up shared memory and terminate.
- terminate if the maximum number of processes to launch have terminated.
- program terminates after 10 real life seconds. This can be done using a timed signal, at which point it should kill all currently running child processes and terminate. It should also catch the ctrl-c signal, free up shared memory and then terminate all children.
- No matter how it terminated, parent should also output the value of the shared clock to the output file.
The children: The child will be given a command line argument when it is exec(), this should be its duration. It should then read the system clock (in shared memory) and add to it the duration (which is in nanoseconds). It then goes into a loop, constantly checking the simulated clock in shared memory. When its time has passed, it should output to stdout its pid, the value of the system clock, and a message that it is terminating. It should then terminate
Hints:
You will need to set up shared memory to allow the processes to communicate with each other involving:
shmget, shmctl, shmat, and shmdt to work with shared memory.
If you abort a process, make sure that the parent cleans up any allocated shared memory before dying. In case you face problems, please use the shell command ipcs to find out any shared memory allocated to you and free it by using ipcrm.
Requirements: use fork, exec (or one of its variants), wait, and exit to manage multiple processes. Use shmctl suite of calls for shared memory allocation. Also make sure that you do not have more than twenty processes in the system at any time. You can do this by keeping a counter in master that gets incremented by fork and decremented by wait.
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started