Write a program that does a probabilistic simulation of a client server system. The
clients generate job packages at random times and place them on the global queue. Every
package takes a random amount of time to execute and if the servers are busy the package
stays on the queue. At every time interval a the client and the server are woken up to simulate
work done during this interval.
The servers need one parameter, the completion rate μ (mu), also called death rate,
of the currently executing process. At every activation of the server, if there is a job executing,
the server generates a random number between zero and one and compares it to μ.
If the random number is smaller than μ the job execution is terminated. If there is no job
executing, the server gets a job from the global queue if available. The state of the server
can be either busy or not-busy.
The clients need one parameter as well, the birth rate l (lambda) of the jobs. Again,
at every activation (if it is not waiting for a previous job to complete) the client generates
a random number between zero and one and compares it to l . If the random number is
smaller than l a new job is generated and placed on the global queue.
The program has to have a simple queue (really simple, it just keeps track of the
number of items in it and nothing else since all the jobs are really the same). It also needs
to keep a few statistics (like number of jobs generated, total number of jobs in the queue,
number of clock ticks so far, etc) from which to compute useful statistics.
The program prints the following job statistics, one per line, properly annotated:
(1) Average waiting time (AWT)
(2) Average execution time (AXT)
(3) Average turnaround time (ATA)
(4) Average queue length (AQL)
(5) Average interarrival time. (AIA)
The command line options to the program are the --lambda [0.005], --mu [0.01],
--servers, --clients, --ticks.
Your program will use pthreads. Every server, and every client will be separate
threads. In addition there is one thread for the clock and this can be the original thread. At
every tick of the clock thread, all other threads get activated, do whatever they need to do
and then wait for the next tick. Whenever the clock sees that all the threads have completed
their work for the current tick, it emits the next tick. The program runs for the
number of ticks specified