The following example shows how to program an M/M/1 queuing system simulation with CNCL events:
// -*- C++ -*-
#include <iostream.h>
#include <CNCL/QueueFIFO.h>
#include <CNCL/EventScheduler.h>
#include <CNCL/FiboG.h>
#include <CNCL/NegExp.h>
#include <CNCL/Moments.h>
#include <CNCL/Job.h>
enum { NJOBS=100000 };
enum { EV_JOB, EV_TIMER_G, EV_TIMER_S }; // Event types for M/M/1 simulation
class Server : public CNEventHandler
{
private:
CNJob *job; // Served job
CNQueueFIFO queue; // CNQueue
CNRandom &rnd_b; // Distribution of service time b
CNMoments t_w, t_b; // Evaluation tau_w, tau_b
enum { ST_WAITING, ST_SERVING };
public:
virtual void event_handler(const CNEvent *ev);
void print_results();
void eval_job(CNJob *job);
Server(CNRandom &rnd) : rnd_b(rnd), job(NIL), t_w("tau_w"), t_b("tau_b")
{
state(ST_WAITING);
}
};
class Generator : public CNEventHandler
{
private:
CNRandom &rnd_a; // Distribution of arrival time a
Server *server; // Connected queue/server
long n;
public:
virtual void event_handler(const CNEvent *ev);
Generator(CNRandom &rnd,Server *serv) : rnd_a(rnd),server(serv),n(0) {}
};
void Generator::event_handler(const CNEvent *ev)
{
if(n == NJOBS)
// Stop simulation
return;
// Incoming event -> generate new Job
send_now(new CNEvent(EV_JOB, server, new CNJob));
// Random delay
send_delay(new CNEvent(EV_TIMER_G), rnd_a());
n++;
}
void Server::event_handler(const CNEvent *ev)
{
switch(state())
{
case ST_SERVING:
switch(ev->type())
{
case EV_JOB:
// Incoming job, put into queue
{
CNJob *job;
job = (CNJob *)ev->object();
job->in = now();
queue.put(job);
}
break;
case EV_TIMER_S:
// Timer event, service time run down
job->out = now();
// Evaluate job
eval_job(job);
delete job;
job = NIL;
// Get new job from queue
if(!queue.empty())
{
job = (CNJob *)queue.get();
job->start = now();
// Random service time
send_delay(new CNEvent(EV_TIMER_S), rnd_b());
state(ST_SERVING);
}
else
state(ST_WAITING);
break;
}
break;
case ST_WAITING:
switch(ev->type())
{
case EV_JOB:
// Incoming job
job = (CNJob *)ev->object();
job->in = now();
job->start = now();
// CNRandom service time
send_delay(new CNEvent(EV_TIMER_S), rnd_b());
state(ST_SERVING);
break;
}
break;
}
}
void Server::eval_job(CNJob *job)
{
t_w.put(job->start - job->in);
t_b.put(job->out - job->in);
}
void Server::print_results()
{
cout << t_w << t_b;
}
main()
{
CNRNG *rng = new CNFiboG;
CNNegExp rnd_a(10, rng);
CNNegExp rnd_b( 5, rng);
Server server(rnd_b);
Generator generator(rnd_a, &server);
CNEventScheduler scheduler;
scheduler.start(new CNEvent(EV_TIMER_G, &generator));
server.print_results();
}
Go to the first, previous, next, last section, table of contents.