You are on page 1of 11

VEBE 6

Semafori
Dosadanja reenja nije lako primeniti na kompleksnije sluajeve sinhronizacije procesa.
U tom kontekstu uvodi se novi metod, koji se naziva semafor. Semafor je nenegativna-integer
promenljiva na koju je pored inicijalizacije, mogue primeniti samo dve vrste nedeljivih
(atomic) operacija. To su signal i wait operacija.
Klasina definicija wait operacije na semaforom S je
wait (S):
while(S<=0) do no-op;
S--;
Klasina definicija signal operacije na semaforom S je
signal (S):
S++;
Operacije wait i signal nad semaforom S su nedeljive, moraju se izvrti do kraja. Dok jedan
proces modifikuje vrednost semafora, nijedan drugi proces ne moe istrovremeno modifikovati
vrednost istog semafora.
Semafori se mogu podeliti u dve grupe:

jaki semafori : oni u kojima svi procesi koji ekaju na primitivi wait smeteni u red
ekanja po FIFO principu(onaj koji najdue eka prvi dobija pravo na izvravanje).

slabi semafori : oni kod kojih svi procesi koji ekaju na semafor nastavljaju sa
izvravanjem po proizvoljnom redosledu.

Semafore takoe moemo podeliti na:

opte (brojake)

binarne(0,1)

Binarni semafori su specijalna klasa semafora, ija vrednost moe biti samo 0 ili 1. Semafori
koji nemaju ovaj limit nazivaju se brojaki semafori (counting semaphor). Birnarni semafori su
laki za implementaciju. Evo jednog primera kako se od 2 binarna semafora S1 i S2 i jedne
celobrojne promenljive C, moe realizovati brojaki semafor S:

Strukture podataka su:


binary-semaphore S1, S2;
int C:
Inicijalizacija:
S1 = 1
S2 = 0
C = initial value of semaphore S
wait operacija wait (S):
while(S<=0) do no-op;
else S--;
wait(S1);
C--;
if (C < 0) {
signal(S1);
wait(S2);
}
signal(S1);
signal operacija signal (S):
S++;
wait(S1);
C ++;
if (C <= 0)
signal(S2);
else
signal(S1);

Korienje semafora
Problem kritine sekcije moemo razreiti pomou semafora mutex (mutual exclusion). U
sluaju da imamo n procesa, problem kritine sekcije razreiemo na sledei nain:
semaphore mutex; /*initially mutex = 1*/
do{
wait(mutex);
critical section
signal(mutex);
remainder section
} while (1);

PRIMER 6-1.cm
// Program demonstrira
// upotrebu semaphora mutex za resenje uzajamnog iskljucivanja
semaphore mutex;
void say_hello (char id) {
wait( mutex );
cout << id <<" "<<id <<" "<<id <<" "<<id <<" "<<id <<" "<< endl;
signal( mutex );
}
main() {
initialsem( mutex, 1 );
cobegin
{
say_hello( 'A'); say_hello('B'); say_hello( 'C');
}
cout << "KRAJ" << endl;
}
Ulazna sekcija svih procesa se razreava sa wait operacijom. Samo jedan proces proi e na
semaforu mutex, ija je inicijalna vrednost = 1, oborie mu vrednost na 0 i ui u svoju kritinu
sekciju. Svi ostali procesi iza toga, bie zaglavljeni na semaforu wait(mutex). Kada proces
napusti kritinu sekciju, oslobodie semafor sa komandom signal(mutex).
Semafori se mogu primeniti i za razne druge probleme u sinhronizaciji kod konkurentnih
procesa. Na primer ako imamo proces P1 sa naredbom S1 i proces P2 sa naredbom S2.
Pretpostavimo da se zahteva da se S2 naredba izvri tek nakon to se kompletira naredba S1.
Problem emo razreiti preko semafora synch, (inicijalno = =0) na sledei nain:
P1

P2

...

....

S1

wait(synch)

signal(synch) S2
PRIMER 6-2.cm
// Program demonstrira
// upotrebu semaphora za sinhronizaciju procesa
// proces C krece tek sa izvrsavanjem kada se A i B zavrse
semaphore mutex;
semaphore A_finish, B_finish;
4

void say_hello (char id){


wait( mutex );
cout << id <<" "<<id <<" "<<id <<" "<<id <<" "<<id <<" "<< endl;
signal( mutex );
}
void A( void ) {
say_hello( 'A' );
signal( A_finish );
}
void B( void ) {
say_hello( 'B' );
signal( B_finish );
}
void C( void ) {
wait( A_finish );
wait( B_finish );
say_hello( 'C' );
}
main() {
initialsem( mutex, 1 );
initialsem( A_finish, 0 );
initialsem( B_finish, 0 );
cobegin {
A(); B(); C();
}
cout << " KRAJ " << endl;
}

Demonstracija upotrebe Semafora za ograniavanje upotrebe nekog resursa.


Poto resursi nisu isti tj. ne zahtevaju iste resurse, brojaki semafori mogu da ogranie
upotrebu resursa u odreenom vremenu. Sledei primer ilustruje 3 procesa teine 1 i 2 procesa
teine 3. Pomou semafora e se ograniiti da se u jednom trenutku mogu izvravati samo
procesi koji zajedno ne zauzimaju vie od 5 jedinica nekog resursa. To znai da se nee moi
izvravati dva procesa teine 3, ili jedan od 3 i 3 od 1 u isto vreme.

PRIMER 6-3.cm
/*Demonstrira ogranicen pristup resursima */
const int m = 5;
semaphore countsem;
void val1 (char id){
int i;
for ( i = 1; i <= m; i = i + 1) {
wait(countsem);
cout <<" 1"<<id<<" 1"<<id<<" 1"<<id
<<" 1"<<id<<" 1"<<id<<" 1"<<id<<" 1"<<id <<endl;
signal (countsem);
}
}
void val3 (char id){
int i;
for ( i = 1; i <= m; i = i + 1) {
wait(countsem);
wait(countsem);
wait(countsem);
cout <<" 3" <<id<<" 3"<<id<<" 3" <<id<<" 3" <<id
<<" 3"<<id<<" 3" <<id<<" 3"<<id<<endl;
signal (countsem);
signal (countsem);
signal (countsem);
}
}
main(){
initialsem(countsem, 5 );
cout <<endl;
cobegin {
val1 ( 'a'); val1 ('b'); val1 ( 'c');
val3('D'); val3('E');
}
cout<< " Kraj"<<endl;
}

Proirena definicija semafora (sleep and wakeup)


Nedostatak i softverske i hardverske realizacije i semafora na ovaj nain je to to se dolazi do
pojave koja se zove busy waiting (zaposleno ekanje): proces se neprestano vrti unutar while
petlje, ne radi nita korisno, svaki put samo proverava vrednost neke promenljive da bi saznao da
li moe ui u svoju kritinu oblast ili ne. Znai i pored toga to dati proces ne radi nita korisno,
troi i procesorsko vreme, a poto znamo da unutar kritine oblasti istovremeno moe biti samo
jedan proces, moemo zamisliti i situaciju da imamo 1001 procesa od kojih se jedan nalazi
unutar kritine oblasti, a ostali stoje u jednom mestu, vrte se u krugu unutar while petlje. Tako
imamo jedan proces koji radi neto korisno i 1000 procesa koji ekajui na taj jedan troe
procesorsko vreme.
Drugi nedostatak prethodnih realizacija je u tome to ne vode rauna o prioritetima procesa:
moe se desiti da najprioritetniji proces ue u kritinu oblast, tek posle mnotva neprioritetnih
procesa.
Da bismo izbegli ove nedostatke softverske i hardverske realizacije, koristiemo pomo
operativnog sistema, tj. kritinu oblast emo realizovati pomou sistemskih poziva. Kod ove
realizacije, kada proces eka da ue u kritinu oblast, postaje blokiran (blocked), sve dok ga
neki drugi proces ne odblokira. Ista se definicija odnosi na semafor. Kada proces eka
pokuavajui wait operaciju na nekom semaforu ija je vrednost 0, on se blokira, umesto da se
vrti u petlji i nekorisno troi procesorsko vreme.
Da bi se eliminisala pojava zaposlenog ekanja, ponovo emo definisati semafor i wait i
signal operaciju. Prva izmena se odnosi na wait operaciju. Kada proces izvrava wait operaciju i
konstatuje da je vrednost semafora 0, proces se tada blokira, pomou sistemskog poziva sleep
koji ga prevodi u red ekanja na semaforu, a proces postaje blokiran, to znai da oslobaa
procesor, koji se predaje nekom drugom procesu koji nije blokiran.
Proces koji je blokiran na semaforu, moe da se restartuje jedino ako neki drugi proces obavi
signal operaciju nad semaforom. Proces se restartuje pomou wakeup sistemskog poziva koji
prebacuje proces iz blokiranog stanja u stanje spremnosti. Realizacija semafora u proirenom
kontekstu je sledea:
Semafor se definie kao struktura ili rekord koja ima svoju celobrojnu vrednost i listu procesa
koji ekaju na semafor. Signal operacija uklanja jedan od procesa iz liste.
typedef struct {
int value;
struct process *L;
} semaphore;
7

Wait operacija dekremetira vrednost semafora i ako je posle toga ona negativna, stavlja proces
u listu procesa koji ekaju na semafor, a blokira proces, to je ilustrovano u sledeem kodu:
wait(S){
S.value--;
if (S.value < 0) {
add this process to S.L;
block();
}
}

//

SL=semaphore list of processes

Signal operacija inkrementira vrednost semafora i ako je posle toga ona negativna ili 0, ukljanja
jedan od procesa iz liste, koga budi sa wakeup() i prebacuje u red ekanja za spremne procese,
to je ilustrovano u sledeem kodu:
signal(S) {
S.value++;
if (S.value <= 0) {
remove a process P from S.L;
wakeup(P); #but which one FIFO, LIFO, priority
}
}
Ovo je prvo reenje koje zahteva intervenciju operativnog sistema, koji ima 2 sistemska poziva
block() ili sleep() i wakeup(). Sva dosadanja reenja su bila softverska ili programerska ili
hardverska ali bez upotrebe operativnog sistema. Zapaa se da u proirenoj definiciji, vrednost
semafora moe biti negativna, to ukazuje da vei broj procesa eka na semafor, a signal
operacija po nekom kriterijumu u takvim sluajevima budi neki od uspavanih procesa. I u
proirenoj definiciji semafora, wait i signal moraju ostati nedeljive operacije.

Monitori
Monitori predstavljaju takoe konstrukciju visokog nivoa koja slui za sinhronizaciju.
Monitor se karakterie skupom programerski definisanih operatora. Reprezentacija monitora
sastoji se od deklaracije promenljivih, ije vrednosti definiu stanje monitora, i procedura i
funkcija unutar monitora. Sintaksa monitora je prikazana na sledeoj slici:
monitor monitor-name {
shared variable declarations
procedure body P1 () {
...
}
procedure body P2 () {
...
}
procedure body Pn () {
...
}
{
initialization code
}
}
Lokalne promenjive u monitiru su vidljive samo unutar monitora.
Konstrukcija monitora dozvoljava da samo jedan proces bude aktivan u monitoru. Monitor
omoguava sinhronizaciju, tako da programer ne treba da pie kod za sinhronizaciju, eksplicitno.
Ali za neke sluajeve, potrebni su dodatni sinhronizacioni mehanizmi, koji dozvojavaju uslovne
konstrukcije. Ako su one potrebne programeru, on treba da definie svoje promenljive, koje se
nazivaju uslovne promenljive:
condition x, y;
Jedine opracije koje mogu da se izvode sa ovim promenljivim su wait i signal. Operacija
x.wait ();
znai da proces koji je pozvao operaciju se suspenduje, blokira, sve dok drugi proces ne pozove
kontra operaciju:
x.signal ();
Operacija x.signal e odblokirati tano jedan blokirani proces. Ako nema blokiranih procesa,
signal operacija ne radi nita, za razliku od signal operacije na semaforu, koja uvek
9

inkrementira vrednost. Na primer, Q je proces blokiran na promenljivoj x u monitoru, a P je


proces koji poalje signal za promenljivu x za isti monitor. Nastupa buenje procesa Q i tada bi
oba procesa bila aktivna u monitoru to nije mogue. To se razreava na vie naina:

proces P e ekati da proces Q napusti monitor

proces Q e saekati da P napusti monitor, pa e onda nastaviti sa radom

Na sledeoj slici je dat prikaz monitora sa uslovnim promenljivim:

PRIMER 6-4.cm
Procedure monV() i monP() u monitoru su napisane da odrade isti posao kao i signal i wait
operacije kod semafora. One se koriste kao i funkcije kod semafora. Program probati nekoliko
puta i prokometarisati rezultate.
/*Implementacija monitora preko semafora */
const int m = 5;
int sum; //deljeni resurs
monitor monSemaphore {
int semvalue;
condition notbusy;
void monP() {
10

if (!semvalue)
waitc(notbusy);
else
semvalue--;
}
void monV() {
if (empty(notbusy))
semvalue++;
else
signalc(notbusy);
}
}

init{semvalue = 1;}
//kraj monitora

void incr (char id){


int i;
for ( i = 1; i <= m; i = i + 1){
monP();
sum = sum + 1;
cout << id << " n =" << sum ;
cout << " " << id << endl;
monV();
}
}
main() {
cout << endl;
sum = 0;
cobegin {
incr ( 'A'); incr ('B'); incr ( 'C');
}
cout << "Suma je "<< sum <<endl;
}

11

You might also like