#include #include #include #include #include #include #include using namespace ssim; using namespace std; float get_req_time(int source_num); float get_pause_time(int source_num); #define LIMIT 1000 // время окончания моделирования #define IDLE 0 //состояние сервера #define RUN 1 //состояние сервера class Job // задание в очереди { public: float time; // время выполнения задания без прерываний int source_num; // номер источника заданий (1 или 2) Job(float t, int s) { time = t; source_num = s; } }; typedef list Queue; // очередь заданий к серверу float get_req_time(int source_num); // длительность задания float get_pause_time(int source_num); // длительность паузы между заданиями static ProcessId server_id; // ссылка на процесс-сервер // событие - запрос к серверу class Req : public Event { public: Req(int num, float reqtime) : e_num(num), e_reqtime(reqtime) {} virtual ~Req() {} // получение атрибутов int getNum() { return e_num; } float getReqtime() { return e_reqtime; } private: int e_num; float e_reqtime; }; // событие - окончание обработки class Fin : public Event { public: Fin() {} virtual ~Fin() {} }; class Start : public Event { public: Start() {} virtual ~Start() {} }; class Client : public Process { public: Client(int num) : c_num(num) {} virtual ~Client() {} virtual void init() { Sim::self_signal_event(new Start, 0); } virtual void process_event(const Event* e) { const Event* ev; if ((ev = dynamic_cast(e)) != 0) { float t = get_req_time(c_num); Req* req = new Req(c_num, t); Sim::signal_event(server_id, req); // delete req; Start* start = new Start; Sim::self_signal_event(start, get_pause_time(c_num)); cout << "client " << c_num << " at time " << Sim::clock() << " length " << t << endl; } else { cerr << "Client(" << c_num << ") received unknown event" << endl; } } private: int c_num; }; class Server : public Process { private: Queue queue; int cpu_state; float run_begin; public: Server() {} ~Server() {} virtual void init() { cpu_state = IDLE; } virtual void process_event(const Event* e) { const Event* ev; if ((ev = dynamic_cast(e)) != 0) { if (cpu_state == IDLE) { cpu_state = RUN; cout << "start running at " << Sim::clock() << " dt " << ((const Req*)ev)->getReqtime() << endl; run_begin = Sim::clock(); Fin* fin = new Fin(); Sim::self_signal_event(fin, ((const Req*)ev)->getReqtime()); } else { cout << "Queueing: time " << ((const Req*)ev)->getReqtime() << " num " << ((const Req*)ev)->getNum() << endl; queue.push_back(new Job(((const Req*)ev)->getReqtime(), ((const Req*)ev)->getNum())); } } else { if ((ev = dynamic_cast(e)) != 0) { cpu_state = IDLE; // выводим запись о рабочем интервале cout << "Работа с " << run_begin << " по " << Sim::clock() << " длит. " << (Sim::clock() - run_begin) << endl; if (!queue.empty()) { Job* rq = queue.front(); queue.pop_front(); Sim::self_signal_event(new Fin(), rq->time); run_begin = Sim::clock(); cout << "From Queue at time " << Sim::clock() << " dt " << rq->time << endl; cpu_state = RUN; delete rq; } } else { cerr << "Server received unknown event" << endl; } } } }; int main(int argc, char **argv) { Client c1(1), c2(2); Server srv; srand(2019); server_id = Sim::create_process(&srv); Sim::create_process(&c1); Sim::create_process(&c2); Sim::set_stop_time(LIMIT); Sim::run_simulation(); return 0; } // main int rc = 0; int pc = 0; float get_req_time(int source_num) { // Для демонстрационных целей - выдаётся случайное значение // при детализации модели функцию можно доработать double r = ((double)rand())/RAND_MAX; cout << "req " << rc << endl; rc++; if(source_num == 1) return r*10; else return r*20; } float get_pause_time(int source_num) // длительность паузы между заданиями { // см. комментарий выше double p = ((double)rand())/RAND_MAX; cout << "pause " << pc << endl; pc++; if(source_num == 1) return p*20; else return p*10; }