Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*Napisati konkurentni program koji modeluje izvrsavanje procesa u multiprogramiranom
- okruzenju na jednom procesoru.
- Procesi su predstavljeni nitima. Svaki proces ima skup instrukcija koje treba da izvrsi, pri
- cemu postoje dva tipa naredbi: NORMAL (instrukcija zahteva odredjeno izracunavanje od procesora) i
- IO (instrukcija zahteva operaciju ulazno/izlaznog uredjaja).
- U sistemu je definisan maksimalan broj instrukcija koje proces moze uzastopno da izvrsi.
- Nakon sto izvrsi taj niz instrukcija, proces prelazi u stanje spreman i drugi
- spreman proces dobija procesor.
- Iz skupa spremnih procesa, naredni proces za izvrsavanje se bira bez odredjenog pravila.
- Bilo koji od spremnih procesa prelazi u izvrsavanje.
- Ako proces izvrsava NORMAL instrukciju, instrukcija traje slucajan vremenski period izmedju
- 10 i 50 ms.
- U sistemu postoji jedan UI uredjaj koji opsluzuje zahteve procesa. UI uredjaj redom opsluzuje pristigle zahteve
- kada postoje zahtevi.
- Ako proces izvrsava IO instrukciju, proces salje zahtev UI uredjaju i odlazi u stanje blokiran.
- Tada drugi proces dobija procesor.
- Kada UI uredjaj zavrsi posao, postavlja prekid i tada se proces prevodi u red spremnih
- procesa. Operacija UI uredjaja traje slucajan period izmedju 100 i 300 ms.
- */
- #include <vector>
- #include <iostream>
- #include <thread>
- #include <mutex>
- #include <condition_variable>
- #include <queue>
- using namespace std;
- using namespace chrono;
- enum INS_TYPE {NORMAL = 0, IO};
- struct Process {
- vector<INS_TYPE>* instructions;
- int id;
- Process(vector<INS_TYPE>* in, int i): instructions(in), id(i) {}
- ~Process() {
- delete instructions;
- }
- };
- struct UiRequest {
- int processId;
- bool finished;
- condition_variable cv;
- UiRequest(int i): processId(i), finished(false) {}
- };
- class System {
- private:
- mutex m;
- int maxInst;
- int activeProcess;
- queue<UiRequest*> uiRequests;
- condition_variable ready; //red spremnih procesa
- condition_variable ui; //cekanje ui uredjaja da neko zatrazi operaciju
- public:
- System(int max): maxInst(max), activeProcess(-1) {}
- void executeProcess(Process& p) {
- int successive = 0;
- for (auto it = p.instructions->begin(); it != p.instructions->end(); it++) {
- unique_lock<mutex> l(m);
- if (activeProcess == -1) {
- activeProcess = p.id; //ako je procesor slobodan zauzmi procesor
- cout << "Proces " << p.id << " zauzeo procesor." << endl;
- }
- while (activeProcess != p.id) {
- cout << "Proces " << p.id << " se uvezuje u red spremnih procesa." << endl;
- ready.wait(l);
- if (activeProcess == -1) {
- activeProcess = p.id; //zauzmi procesor
- cout << "Proces " << p.id << " zauzeo procesor." << endl;
- }
- }
- if (*it == NORMAL) {
- l.unlock();
- this_thread::sleep_for(milliseconds(rand()%40 + 10));
- l.lock();
- //ako je izvrsen maksimalan broj uzastopnih instrukcija ili su izvrsene sve instrukcije procesa
- if (++successive == maxInst) {
- cout << "Proces " << p.id << " oslobadja procesor. Broj uzastopnih instrukcija: "
- << successive << endl;
- successive = 0;
- activeProcess = -1; //oslobodi procesor
- ready.notify_one(); //aktiviraj sledeci iz reda spremnih
- //cooldown period da ne uzme ovaj isti proces odmah procesor
- l.unlock();
- this_thread::sleep_for(milliseconds(100));
- }
- } else {
- UiRequest* req = new UiRequest(p.id);
- uiRequests.push(req);
- ui.notify_one();
- cout << "Proces " << p.id << " odlazi u cekanje zbog UI operacije." << endl;
- while (!req->finished) {
- successive = 0;
- activeProcess = -1;
- ready.notify_one();
- req->cv.wait(l);
- cout << "UI uredjaj iz blokiranja probudio proces " << p.id << endl;
- }
- delete req;
- cout << "Proces " << p.id << " vise nije blokiran." << endl;
- }
- }
- //kada zavrsi izvrsavanje, naredni proces zauzima procesor
- unique_lock<mutex> l(m);
- if (activeProcess == p.id) {
- activeProcess = -1;
- ready.notify_one();
- }
- }
- void executeUi() {
- while (true) {
- unique_lock<mutex> l(m);
- while (uiRequests.empty()) {
- cout << "Uredjaj ide u cekanje" << endl;
- ui.wait(l);
- }
- UiRequest* req = uiRequests.front();
- uiRequests.pop();
- cout << "Ui uredjaj obradjuje zahtev procesa " << req->processId << endl;
- l.unlock();
- this_thread::sleep_for(milliseconds(rand()%200 + 100));
- l.lock();
- req->finished = true;
- req->cv.notify_one();
- cout << "Ui uredjaj izvrsio zahtev procesa " << req->processId << endl;
- }
- }
- };
- mutex term_m;
- void p(System& s, int id) {
- vector<INS_TYPE>* instructions = new vector<INS_TYPE>();
- for (int i = 0 ; i < 10; i++) {
- instructions->push_back((INS_TYPE)(rand()%10 == 1)); //9:1 sanse da ce biti NORMAL instrukcija
- }
- Process p(instructions, id);
- s.executeProcess(p);
- unique_lock<mutex> l(term_m);
- cout << "Proces " << id << " se zavrsio." << endl;
- }
- void uiDevice(System& s) {
- s.executeUi();
- }
- int main() {
- srand(time(NULL));
- System system(3);
- thread t[5];
- thread uiThread = thread(uiDevice, ref(system));
- uiThread.detach();
- for (int i = 0; i < 5; i++) {
- t[i] = thread(p, ref(system), i+1);
- }
- for (int i = 0; i < 5; i++) {
- t[i].join();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement