OS1/Modifikacije jun 2021
< ОС1
Pređi na navigaciju
Pređi na pretragu
Sledeće modifikacije su se pojavile na odbrani projekta u junskom roku 2021.
20 poena
- Sledeća stavka ista je kao 1. zadatak sa drugog kolokvijuma u junskom roku 2017. godine: Školsko jezgro treba proširiti konceptom barijere ("ograda", "rampa", engl. barrier) čiji je interfejs dat dole. Semantika ovog koncepta i operacija nad njim je sledeća:
- Barijera može biti u jednom od dva stanja: otvorena ili zatvorena. Barijera se inicijalizuje zadatim stanjem (argument konstruktora). Nit u čijem kontekstu se kreira barijera (tj. izvršava konstruktor) je njen vlasnik.
void Barrier::pass()
: ukoliko pozivajuća nit nije vlasnik ove barijere, ova operacija nema efekta - nit nastavlja svoje izvršavanje; ukoliko je pozivajuća nit vlasnik barijere, a barijera zatvorena, nit se suspenduje (blokira) sve dok se barijera ne otvori; ako je barijera otvorena, nit nastavlja izvršavanje bez blokade;void Barrier::close()
: zatvara barijeru;void Barrier::open()
: otvara barijeru i eventualno deblokira nit koja je na barijeri blokirana.
- Napisati javni test sa dve niti A i B. Nit B pravi globalni semafor sa vrednošću 0 i globalnu barijeru sa vrednošću 1, a nit A uposleno čeka dok se oni ne naprave. Nit A treba ciklično da poziva
Barrier::open()
,Barrier::pass()
iSemaphore::wait(0)
, dok nit B treba ciklično da pozivaBarrier::pass()
,Barrier::close()
iSemaphore::signal()
.
class Barrier {
public:
Barrier (int open=1);
void open();
void close();
void pass();
};
Rešenje
Okvirno rešenje može se naći kao rešenje pomenutog kolokvijuma. Test opisan tekstom zadatka.
#include "thread.h"
#include "semaphor.h"
#include "barrier.h"
#include "intLock.h"
Semaphore *s = 0;
Barrier *b = 0;
Semaphore waiter(0);
class MyA : public Thread {
public:
MyA() : Thread() {}
~MyA() { waitToComplete(); }
protected:
void run() {
while (s == 0 || b == 0) {}
while (1) {
b->open();
intLock
cout << "A opened the barrier" << endl;
intUnlock
b->pass();
intLock
cout << "A passed the barrier" << endl;
intUnlock
s->wait(0);
}
}
};
class MyB : public Thread {
public:
MyB() : Thread() {}
~MyB() { waitToComplete(); }
protected:
void run() {
s = new Semaphore(0);
b = new Barrier(1);
while (1) {
b->pass();
intLock
cout << "B passed the barrier" << endl;
intUnlock
b->close();
intLock
cout << "B closed the barrier" << endl;
intUnlock
s->signal();
waiter.wait(30);
}
}
};
void tick() {}
int userMain(int argc, char *argv[]) {
MyA a;
MyB b;
a.start();
b.start();
a.waitToComplete();
b.waitToComplete();
}
30 poena
- Napraviti da se nakon poziva
fork()
kao sledeća nit za izvršavanje izabere dete (pre izlaska izfork()
u roditeljskoj niti). Takođe, forsirati da se prvo biraju niti bez dece. - Napisati test primer koji testira zadatu funkcionalnost. Na primer, može da izgleda poput:
int result = Thread::fork();
if (result != -1) {
if (result == 0) {
intLock
cout << "Child!" << endl;
intUnlock
Thread::exit();
} else {
intLock
cout << "Parent!" << endl;
intUnlock
Thread::waitForForkChildren();
}
}
Rešenje
- Rešenje za biranje deteta jeste da se u
PCB
doda pokazivač na dete koje je izabrano koji se postavlja na novonapravljeno dete ufork()
, proverava da li jenullptr
u tajmeru (u koji se ušlo pozivom funkcijedispatch()
unutar funkcijefork()
), ako nije onda se nit koja je sledeća za izvršavanje postavlja na to dete i pokazivač se vraća nanullptr
. - Jedno rešenje za forsiranje niti koje nemaju decu jeste da se, ukoliko se ne dešava biranje deteta, iz
Scheduler
vade niti dok se ne pronađe nit bez dece (koja se odmah postavi kao nit za izvršavanje) ili dok se ne izbace sve niti, ako su izvađene niti sa decom one se ubacuju u drugu listu i na kraju se vraćaju nazad uScheduler
. Ukoliko nit bez dece nije pronađena, između vađenja i vraćanja niti proverava se da li je izvučena ijedna nit bez dece i vadi se jedna nit sa decom ukoliko nije.