Documente Academic
Documente Profesional
Documente Cultură
2
3.1. Exemple introductive.................................................................................................................................................2
3.1.1. Administrarea tamponat a intrrilor-ieirelor...................................................................................................2
3.1.2. Comanda unui proces industrial.........................................................................................................................3
3.2. Noiune de proces secvenial.....................................................................................................................................3
3.2.1. Proces unic. Context...........................................................................................................................................3
3.2.2. Relaii ntre procese............................................................................................................................................4
3.2.2.1. Mulimi de procese. Paralelism...................................................................................................................4
3.2.2.2. Concurena proceselor. Resurse virtuale.....................................................................................................5
3.2.2.3. Excludere mutual.......................................................................................................................................6
3.3. Sincronizarea proceselor...........................................................................................................................................6
3.3.1. Exprimarea i implementarea restriciilor de precedare.....................................................................................6
3.3.2. Probleme de realizare a sincronizrii.................................................................................................................7
3.3.3. Monitorul mecanism de sincronizare..............................................................................................................8
3.3.3.1. Definiii........................................................................................................................................................8
3.3.3.2. Exemple de utilizare....................................................................................................................................9
3.4. Implementarea sincronizrii....................................................................................................................................10
3.4.1. Probleme-tip.....................................................................................................................................................10
3.4.2. Administrarea unei resurse partajate................................................................................................................10
3.4.2.1. Alocarea resurselor banalizate...................................................................................................................10
3.4.2.2. Modelul cititorului i redactorului.............................................................................................................12
3.4.3. Comunicarea ntre procese...............................................................................................................................13
3.4.3.1. Modelul productorului i consumatorului...............................................................................................13
3.4.3.2. Primitive de comunicare............................................................................................................................14
3.4.3.3. Aplicaii : relaia client-server...................................................................................................................16
3.4.4. Administrarea intrrilor-ieirilor.......................................................................................................................16
3.4.4.1. Administrarea unui periferic......................................................................................................................16
3.4.4.2. Buferizarea imprimrii..............................................................................................................................17
3.4.5. Sincronizare temporal.....................................................................................................................................18
3.5. Gestionarea dinamic a proceselor..........................................................................................................................19
3.6. Sincronizarea n Windows.......................................................................................................................................21
3.6.1. Procese i fire...................................................................................................................................................21
3.6.2. Necesitatea sincronizrii...................................................................................................................................21
3.6.3. Structura mecanismului de sincronizare n Windows......................................................................................21
3.6.4. Administrarea obiectelor de sincronizare n Windows.....................................................................................22
3.6.4.1. Excluderea mutual...................................................................................................................................22
3.6.4.2. Evenimentele.............................................................................................................................................22
3.6.4.3. Semafoarele...............................................................................................................................................22
3.6.4.4. Seciunile critice........................................................................................................................................22
3.6.4.5. Protejarea accesrii variabilelor................................................................................................................23
3.6.4.6. Sincronizarea n MFC................................................................................................................................23
3.6.5. Exemplu de sincronizare n Windows..............................................................................................................23
3.6.6. Utilizarea seciunilor critice n Windows.........................................................................................................24
3.6.6.1. Structura RTL_CRITICAL_SECTION.....................................................................................................25
3.6.6.2. Funcii API pentru seciunile critice..........................................................................................................26
3.6.6.3. Clase de seciuni critice.............................................................................................................................28
3.6.6.4. Depanarea seciunilor critice.....................................................................................................................28
3.7. Exerciii la capitolul 3.............................................................................................................................................31
tm1 tm2
(memorie) (memorie)
td
(disc)
Fig.3.1. Gestionarea buferizat a unei imprimante
Aceste patru activiti sunt n mare msur autonome, or ele sunt executate pe procesoare distincte, cu programe
diferite. Ele nu sunt totui independente, deoarece acceseaz obiecte comune: dou tampoane n memorie, tm1 i tm2 i
un tampon pe disc, td. Pot fi evideniate dou tipuri de condiii, care trebuie respectate:
1) Condiii, care stabilesc posibilitatea existenei unor activiti
O nregistrare nu poate fi preluat dintr-un tampon nainte de a nu fi depozitat aici. Tampoanele au capaciti
limitate; dac un tampon este ocupat cu nregistrri, care nu au fost nc preluate, este imposibil depozitarea fr a
pierde informaii. Aciunile de depozitare i preluare sunt, deci, supuse unor condiii de posibilitate de existen,
enumerate mai jos.
Activitate Aciune Condiie
SL scriere n tm1 tm1 nu este plin
SD citire din tm1 tm1 nu este vid
SD scriere n td td nu este plin
CD citire din td td nu este vid
CD scriere n tm2 tm2 nu este plin
IF citire din tm2 tm2 nu este vid
Execuia activitilor modific veridicitatea acestor condiii: astfel, imprimarea unei linii pune n TRUE condiia
tm2 nu este plin.
O activitate, care nu poate executa o aciune, deoarece condiia asociat are valoare FALSE, trebuie s atepte, adic
execuia unei aciuni este retardat pn cnd valoarea logic a condiiei devine TRUE. n capitolul 2 a fost discutat
realizarea acestui mecanism de ateptare i continuare cu ajutorul ntreruperilor.
2) Condiii de validitate a informaiilor partajate
Dac vom examina procesul de accesare a tampoanelor, vom descoperi o alt form de interaciune, cauzat de
posibilitatea de accesare simultan de ctre dou activiti a unui amplsament de memorie. Astfel, dac SD citete
coninutul unei nregistrri din tm1 pe care SL este n curs de a o modifica, rezultatul acestei citiri risc s fie incoerent,
dac nu au fost luate msuri speciale de precauie. Problema poate fi rezolvat impunnd una din activiti, aflate n
conflict, s atepte pn cnd cealalt va termina accesarea.
Concluziile acestei prime analize:
Lucrarea imprimare tamponat este realizat prin patru activiti simultane, n mare msur autonome, care
coopereaz pentru atingerea scopului final.
n realitate, citirea i scrierea pe disc sunt executate pe acelai canal, ceea ce poate impune unele restricii privind simultaneitatea executrii lor.
Vom ignora aici aceste restricii, justificnd mai apoi acest mod de procedare.
ntr-un mod mai riguros ar trebui s adugm aici punctele ntreruptible care pot fi prezente n unele instruciuni de lung durat; o executare a
unei asemenea instruciuni poate fi considerat o suit de mai multe aciuni.
Pentru comoditatea expunerii considerm, c sfritul unei aciuni i nceputul aciunii urmtoare sunt dou evenimente distincte, datele crora sunt
diferite, dei strile corespunztoare sunt identice.
p q p q p q
(2)
p q
(3)
2) Alegerea nivelului de baz depinde de fineea fenomenelor, care dorim s le considerm elementare. Dac
trebuie s studiem executarea instruciunilor n pipe-line pe un procesor microprogramat, n calitate de nivel
de baz va fi ales nivelul microinstruciunilor, iar contextul va fi completat cu memoria microprogramelor i
registrele interne.
Vom examina realizarea, la nivelul de baz, a unei scheme de execuie de tipul 2. La fiecare realocare a procesorului,
contextul procesului curent trebuie salvat, pentru a permite reluarea ulterioar a acestei execuii. Dac memoria are o
capacitate suficient pentru a pstra toate segmentele, doar contextul procesorului trebuie salvat. Dac memoria
principal poate conine, la un moment de timp dat, doar segmentul procedur i datele unui singur proces, aceste
segmente de asemenea trebuie salvate pe disc. Aceast remarc justific definiia operaional, adesea ntlnit, a
contextului unui proces ca mulime a informaiilor care trebuie salvat pentru a permite reluarea ulterioar a
procesului, dac execuia acestuia a fost ntrerupt.
3.2.2.2. Concurena proceselor. Resurse virtuale
Situaia descris de schemele 1 i 2 nu rezult dintr-o legtur logic ntre p i q, ci doar din existena unui singur
procesor. Ea poate fi caracterizat astfel: fie o mulime de procese contextele crora au un obiect comun, care poate fi
utilizat la un moment de timp dat de un singur proces. Se va spune n acest caz, c obiectul constituie o resurs critic
pentru procesele date sau c procesele sunt n excludere mutual (excludere reciproc sau concuren) pentru
utilizarea unei resurse. n situaia descris, procesorul este o resurs critic pentru procesele p i q.
Observm c excluderea mutual a unei resurse conduce la serializarea execuiei proceselor concurente, n cazul
unor aciuni, care cer aceast resurs (n exemplul dat, toate aciunile). Schemele 1 i 2 difer doar prin nivelul de finee
la care este executat serializarea.
Funcionarea corect a unei mulimi de procese, care particip la ndeplinirea unei lucrri comune, implic relaii
logice de cooperare (v.3.1.1). Este comod s se separe aceast cooperare de concurena pentru resursele fizice cu
scopul de a simplifica nelegerea i aplicarea celor dou tipuri de relaii. Pentru aceasta este folosit noiunea de
resurse virtuale: fiecrei resurse fizice critice i se asociaz tot attea copii imaginare (sau virtuale) ale acestei resurse
cte procese concurente solicit utilizarea ei. Suntem nevoii s tratm dou probleme distincte:
1) respectarea relaiilor de cooperare ntre procesele, care, fiecare posed (conceptual) resursele fizice solicitate i
pentru care paralelismul n execuie nu este restricionat de competiia pentru resurse,
Excluderea mutual const n extinderea pentru secvena de aciuni a proprietii de indivizibilitate a aciunilor
nivelului de baz (aciuni atomare). Posibilitatea executrii unor aciuni atomare se afl la baza mecanismelor care
realizeaz sincronizarea.
aut(ps) : f:=true
A fost introdus variabila de stare f pentru a exprima condiia procesul p a terminat aciunea scriere(a).
Exemplul 3.7: var n : integer init 0;
procesul pi
<debut_i>;
n:=n+1
ps: <continuare_i>
aut(psi): n=N (i=1,...,N);
Variabila de stare n este n acest caz numrul procesului sosit n punctul de rendez-vous.
Problema ar fi uor de rezolvat, dac fiecare proces ar dispune de un ceas propriu: ar fi suficient s se introduc n contor valoarea t i s se atepte
ntreruperea la trecerea prin zero. Realizarea primitivei suspendare cu ajutorul unui ceas unic comun presupune ataarea fiecrui proces a unui ceas
virtual.
procesul 1 procesul 2
copie
date date
stiv stiv
procesul fiu
procesul printe
Fig.4.4. Crearea proceselor cu ajutorul instruciunii fork
if (fork() == 0) if (fork() == 0)
codul procesului fiu codul procesului fiu
else else
codul procesului printe codul procesului printe
#include <windows.h>
#include <iostream.h>
void main()
{
DWORD res;
// eliberm obiectul
cout<<"Acum eliberm obiectul\n"; cout.flush();
ReleaseMutex(mutex);
}
// nchidem descriptorul
CloseHandle(mutex);
}
Pentru a controla modul de funcionare a mecanismului de excludere mutual se vor lansa dou instane ale acestei
aplicaii. Prima instan va ocupa obiectul imediat i-l va elibera doar peste 10 secunde. Numai dup aceasta instana a
doua va reui s ocupe obiectul. n acest exemplu obiectul de sincronizare este folosit pentru sincronizarea proceselor,
din care cauz n mod obligatoriu trebuie s aib nume.
// Firul #1
void Proc1()
{
if (m_pObject)
m_pObject->SomeMethod();
}
// Firul #2
void Proc2(IObject *pNewObject)
{
if (m_pObject)
delete m_pObject;
m_pObject = pNewObject;
}
n acest exemplu exist pericolul potenial de apelare m_pObject->SomeMethod() dup ce obiectul a fost distrus
cu ajutorul delete m_pObject, deoarece n sistemele de operare cu multitasking controlat execuia oricrui fir poate fi
ntrerupt n cel mai neconvenabil (pentru firul dat) moment i s nceap execuia unui alt fir. Pentru exemplul nostru
momentul nedorit este atunci cnd firul #1 a testat deja m_pObject, dar nu a reuit s apeleze SomeMethod().
Execuia firului #1 a fost ntrerupt i a nceput execuia firului #2. Iar firul #2 reuise deja s apeleze destructorul
obiectului. Ce se va ntmpla atunci cnd firului #1 i se va acorda din nou timp de procesor i va fi apelat
SomeMethod() al unui obiect deja inexistent? Greu de presupus.
Aici ne vin n ajutor seciunile critice. S modificm exemplul de mai sus.
// Firul #1
void Proc1()
{
::EnterCriticalSection(&m_lockObject);
if (m_pObject)
m_pObject->SomeMethod();
::LeaveCriticalSection(&m_lockObject);
}
// Firul #2
void Proc2(IObject *pNewObject)
{
::EnterCriticalSection(&m_lockObject);
if (m_pObject)
delete m_pObject;
m_pObject = pNewObject;
::LeaveCriticalSection(&m_lockObject);
}
// nc Firul #1
void Proc2()
{
::EnterCriticalSection(&m_lock);
// ...
::LeaveCriticalSection(&m_lock);
}
ntr-adevr, seciunile critice sunt destinate s protejeze datele la accesarea din cteva fire. Utilizarea multipl a
uneia i aceeai seciuni critice de un singur fir nu va genera eroare, ceea ce este normal. Trebuie doar s avem grij ca
numrul de apeluri ::EnterCriticalSection() i ::LeaveCriticalSection() s coincid i totul va fi n regul.
Cmpul OwningThread conine 0 n cazul seciunilor critice libere sau identificatorul unic al firului-posesor. Acest
cmp este testat, dac la apelul ::EnterCriticalSection() cmpul LockCount, dup incrementarea cu o unitate, a
devenit mai mare ca 0. Dac OwningThread coiincide cu identificatorul unic al firului curent, atunci valoarea lui
RecursionCount crete cu o unitate i ::EnterCriticalSection() este returnat imediat. n caz contrar
::EnterCriticalSection() va atepta pn firul, care posed seciunea critic, va apela ::LeaveCriticalSection() de un
numr necesar de ori. Cmpul LockSemaphore este folosit, dac este necesar s se atepte pn seciunea critic este
eliberat. Dac LockCount este mai mare ca 0 i OwningThread nu coiincide cu identificatorul unic al firului curent,
atunci firul blocat creaz un obiect al nucleului eveniment i apeleaz ::WaitForSingleObject(LockSemaphore).
Firul posesor, dup decrementarea cmpului RecursionCount, testeaz acest cmp i dac valoarea lui este 0, iar
LockCount este mai mare ca 0, constat c exist minimum un fir n ateptarea momentului cnd LockSemaphore se
va afla n starea sosit. Pentru aceasta firul-posesor apeleaz ::SetEvent() i un fir oarecare (doar unul) dintre cele
blocate este deblocat i are acces la datele critice.
RtlpWaitForCriticalSection(pcs);
}
pcs->OwningThread = (HANDLE)::GetCurrentThreadId();
pcs->RecursionCount = 1;
}
return TRUE;
}
class CScopeLock
{
LPCRITICAL_SECTION m_pCS;
public:
CScopeLock(LPCRITICAL_SECTION pCS) : m_pCS(pCS) { Lock(); }
CScopeLock(CLock& lock) : m_pCS(&lock.m_CS) { Lock(); }
~CScopeLock() { Unlock(); }
void Lock() { ::EnterCriticalSection(m_pCS); }
void Unlock() { ::LeaveCriticalSection(m_pCS); }
};
Clasele CLock i CAutoLock sunt utilizate, de obicei, pentru sincronizarea accesrii variabilelor clasei, iar
CScopeLock este destinat, n special, pentru a fi utilizat n proceduri. Compilatorul singur va avea grij s apeleze
::LeaveCriticalSection() prin intermediul destructorului. Urmeaz un exemplu de folosire a CScopeLock.
CAutoLock m_lockObject;
CObject *m_pObject;
void Proc1()
{
CScopeLock lock(m_ lockObject); // apelarea lock.Lock();
if (!m_pObject)
return; // apelarea lock.Unlock();
m_pObject->SomeMethod();
// apelarea lock.Unlock();
}
3.6.6.4. Depanarea seciunilor critice
Depanarea seciunilor critice este o ocupaie foarte interesant, dar i dificil. Poi cuta ore i chiar zile n ir cauza
apariiei unei probleme. Erorile, legate de seciunile critice sunt de dou tipuri: de realizare i de arhitectur. Erorile de
realizare pot fi depistate relativ uor i, de regul, sunt generate de utilizarea incorect (lipsa perechii) a apelurilor
::EnterCriticalSection() i ::LeaveCriticalSection(). Urmeaz un fragment de cod n care este omis apelul
::EnterCriticalSection().
// n procedur se presupune, c m_lockObject.Lock(); a fost deja apelat
void Pool()
{
for (int i = 0; i < m_vectSinks.size(); i++)
// Firul #2
void Proc2()
{
::EnterCriticalSection(&m_lock2);
// ...
::EnterCriticalSection(&m_lock1);
// ...
::LeaveCriticalSection(&m_lock1);
// ...
::LeaveCriticalSection(&m_lock2);
}
Pot s apar probleme i n cazul copierii unor seciuni critice. Este greu de presupus c codul de mai jos a fost scris
de un programator sntos:
CRITICAL_SECTION sec1;
CRITICAL_SECTION sec2;
// ...
sec1 = sec2;
Din atribuirea de mai sus este dificil s obii foloase. Dar fragmentul urmtor poate fi adesea ntlnit:
// Firul #2
void IObject2::SomeMethod()
{
// Apelm metoda obiectului #1 din firul obiectului #2
m_pObject1->Proc2();
}
// Firul #2
void IObject1::Proc2()
{
// ncercm s intrm n seciunea critic a obiectului #1
m_lockObject.Lock();
// Aici nu vom ajunge niciodat
m_lockObject.Unlock();
}
Dac n acest exemplu nu ar fi avut loc comutarea firelor, toate apelurile ar fi avut loc n firul obiectului #1 i nu am
fi avut probleme. Exemple de acest gen stau la baza tehnologiei compartimentului COM (apartments). Nu sunt
recomandate apelurile obiectelor, dac au avut loc intrri n seciunile critice. Primul exemplu din acest subparagraf va
fi rescris astfel:
// Firul #2
void Proc2(IObject *pNewObject)
{
m_lockObject.Lock();
m_pObject = pNewobject;
m_lockObject.Unlock();
}
Accesul la obiect a rmas ca i mai nainte sincronizat, dar apelul SomeMethod() are loc n afara seciunii critice.
Situaia a fost aproape rezolvat. Mai exist o problem mic. S cercetm mai atent Proc2():
Ua de intrare i cea de comunicare dintre sala de ateptare i salonul brbierului nu permit intrarea simultan a mai
multor clieni (doar unul singur poate trece prin fiecare ua la un moment de timp dat). Aceste ui au un mecanism
culisant, care face ca una din ele s fie nchis, atunci cnd cealalt este deschis. Brbierul invit urmtorul client,
atunci cnd termin deservirea clientului curent. Dac sala de ateptare este goal el doarme. Dac un client gsete
brbierul dormind, l trezete, altfel i ateapt rndul n sala de ateptare.
Reprezentnd brbierul i clienii prin procese, programai funcionarea acestui sistem cu ajutorul unui monitor.
Exerciiul 3.4. O linie de cale ferat, care leag dou orae A i B, conine o poriune cu un singur drum. Vom
reprezenta trenurile prin procese conform schemei de mai jos:
trenurile A B trenurile B A
... ...
sens_unic.intrare_vest sens_unic.intrare_est
<traversare sens unic> <traversare sens unic>
sens_unic.ieire_est sens_unic.ieire_vest
... ...
B
A
Rolul monitorului sens_unic este s garanteze c toate trenurile, angajate la un moment de timp dat pe poriunea cu
un singur drum, circul n aceeai direcie.
1) S se elaboreze programul monitorului sens_unic, presupunnd c numrul trenurilor prezente pe poriunea cu
un singur drum, nu este limitat.
2) Aceeai problema, dar pentru un numr limitat N de trenuri.
3) Examinai n ambele cazuri riscul de blocare i mijloacele de evitare ale acestora.
Exerciiul 3.5. Cinci filozofi stau la o mas conform schemei de mai jos.
Filosoful 0
Filosoful 4 Filosoful 1
Filosoful 3 Filosoful 2