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.