Számítógép-hálózatok: Labor 7
Szálak szinkronizálása (Ro- Sincronizarea threadurilor)
A gyakorlat célja: Megismerkedni a szálak szinkronizációs metódusaival és alkalmazásuk a Windows környezetben. Elméleti bevezető: Szálak szinkronizálása: A többszálú programozás majdnem olyan, mint a szekvenciális programozás, az egyetlen eltérés abból adódik, ha szükséges megosztott erőforrások, vagy más szál szolgáltatásainak használata amikoris szükséges szinkronizáció használata. Szemafor (Semafor - Semaphor) A szemafor a folyamatok és szálak szinkronizálására volt bevezetve Dijistra által, amely a közös erőforrások védelmét kritikus szekciók és kizárólagos hozzáféréssel biztosítja. Formálisan a szemafort egy (v(s),c(s))párossal lehet definiálni ahol a v(s) a szemafor értéke, ami egy egész érték és annak az iniciális értéke a v0(s) és a c(s) a várakozási listát jelöli és referenciákat tartalmaz a folyamatokra és szálakra, amelyek az s szemaforra várakoznak. Kezdetben ez a lista üres. Két atomikus (oszthatatlan művelet, amit megszakítások sem szakíthatnak meg) műveletet definiálunk a szemafor kezelésére: P(s) és V(s) (WAIT és SIGNAL). A P(s) művelettel csökkenteni tudjuk az s szemafor értékét egyel és a P(s)-t meghívó szál (A) a megkapja a hozzáférést a védett erőforráshoz. v(s)=v(s)-1; if v(s) < 0 { Állapot(A) := VÁR; c(s)<==A; átadjuk a vezérlést a ÜTEMEZŐ-nek } másképp { átadjuk a vezérlést az A-nak } Az A szál által végrehajtott V(s) művelet növeli a szemafor értékét eggyel és felszabadítja a használt erőforrást.
Számítógép-hálózatok: Labor 7 v(s)=v(s)+1; if v(s) <= 0 { c(s)==>B; Állapot(B) := KÉSZ; átadjuk a vezérlést a ÜTEMEZŐ-nek } másképp { átadjuk a vezérlést az A-nak } A szemafor iniciális értéke a v0(s) jelentős mert itt határozzuk meg, hogy hányan férhetnek hozzá egyidejűleg a kritikus szekció által védett erőforráshoz. Mutex változó (mutual exclusion) Több szál által használt osztott erőforrások védelmére alkalmas eszköz. Koncepcionálisan a mutex egy bináris szemafor. Segítségével implementálják a kritikus szekciókat és a monitorokat (későbbiekben tárgyalunk róluk). A mutexnek két lehetséges állapota van: lezárt (0)– egy szál tulajdona Soha sem lehet egyszerre több szálnak a tulajdona. Ha egy szál egy lezárt mutexet szeretne megkapni akkor várnia kell amíg azt felszabadítja a foglaló szál azt felszabadítja. nyított (1)– egyetlen szálnak sem a tulajdona Lehetséges műveletek egy mutexen:
Inicializálás (statikus vagy dinamikus) m szemafor, v0(m)=1 lezárás (hozzáférés igénylése a védett erőforráshoz = mutex igénylése) P(m) nyitás (felszabadítja az erőforrást) V(m) megsemmisítése a mutex változónak megsemmisítése az m szemafornak
Feltételes változók A feltételes változók szinkronizációs és kommunikációs objektumok aa egy feltétel teljesülésére várakozó szál és feltételt teljesítő szál között. A feltételes változóhoz hozzá van rendelve egy: predikátum – a feltétele aminek teljesülnie kell
Számítógép-hálózatok: Labor 7
mutex változó - mutex változó biztosítja hogy a feltétel ellenőrzése és a várakozás vagy a feltétele ellenőrzése és teljesülésének jelzése atomi műveletként legyen végrehajtva.
Lehetséges műveletek egy feltételes változón:
Inicializálás - statikus vagy dinamikus Várakozás (WAIT) – a szál várakozik amíg kívülről jelzik a feltétel teljesülését Jelzés (NOTYFY) Az aktuális szál jelez az összes szálnak akik várják feltétel megvalósulását Megsemmisítés
Ellenőrzési koncepció (Conceptul de monitor - Monitor concept): A monitor objektum egy több szál által használt eljárás nem párhuzamos végrehajtását teszi lehetővé. Ötvözi az objektum orientált programozást a szinkronizációs metódusokkal. A monitor objektum áll: 1. osztott adat 2. ezeket az adatokat feldolgozó eljárások 3. monitort inicializáló metódusokat Másképp: mindegyik eljárás halmazt egy monitor kontrolál. A többszálas alkalmazás futásakor, a monitor egyetlen szálnak engedélyezi egy adott időpontban az eljárás végrehajtását. Ha egy szál éppen egy monitor által kontrolált eljárást akar futtatni akkor az lefoglalja a monitort. Abban az esetben ha a monitor már foglalt akkor várakozik amíg a monitort lefoglaló szál befejezi a adott eljárás végrehajtását és felszabadítja a monitort. Kritikus rész és erőforrás, kölcsönös kizárás (Sectiune si resursa critica – Critical resurses and section, mutual exclusion): Két szál kölcsönös kizárása kifejezi hogy egy időben csak az egyik szál futhat Kritikus szekció azt jelenti, hogy egy időben csak egyetlen szál hajthatja végre Kritikus erőforrás jelzi, hogy egy adott erőforráshoz egy időben csak egy szál vagy folyamat férhet hozza. Egy jól definiált kritikus szekció a következő tulajdonságokkal rendelkezik: Egy adott időpontban egyetlen szál található a kritikus szekcióban, bármely más szál ami hozzá akar férni a kritikus részhez, csak azután tud ami után a szekciót lefoglaló szál befejezi annak futtatását. A szálak relativ sebességei nem ismertek Bármely szál leállítása csak a kritikus szekción kívül történhet Egyetlen szál sem fog végtelen időt várni a kritikus részben Legegyszerűbb megvalósítása egy kritikus szekciónak egy bináris szemafor segítségével lehetséges.
Számítógép-hálózatok: Labor 7 Szinkronizáció megvalósítása Windows környezetben A szinkronizációs és kommunikációs mechanizmusokat a Win32API- keresztül lehet elérni. Ilyen szinkronizációs objektumok szemafor, események, mutex változók, kritikus szekciók. Ezeknek az objektumoknak két állapotuk van: jelzet – feltételezi bizonyos feltételek teljesülését és jelzi a várakozó szálaknak ennek a teljesülését; nem jelzett. Várakozásos függvények A legegyszerűbb kommunikálás a szálak között a szinkronizációs objektumok segítségével történő jelzések. Ilyen objektumok a szemaforok, események és mutex változók. Ezek az objektumok úgy vannak tekintve az Windowsban mint amelyek jelzett állapotba fognak kerülni. A várakozásos függvények a következő képpen modósítják a szinkronizációs objektumok állapotát: ha szemafor akkor ennek az értéke egyel csökken és nem jelzett állapotba kerül. Ha mutex akkor nem jelzett állapotba kerül. Win32API várakozós függvényei: WaitForSingleObject és WaitForSingleObjectEx a bemenő paraméterei egy szinkronizációs objektum kezelő (Handle). Felfüggeszti a szál futását amíg az objektum jelzet állapotba nem kerül. Lehetséges a várakozási idő beállítása is ha az adott paramétere különbözik INFINITE -től. SignalObjectAndWait Egy objektumnak jelzettre modósítja állapotát és várakozik hogy egy másik objektum állapota jelzett legyen. WaitForMultipleObject és WaitForMultipleObjectEx Egy szinkronizációs objektum mező a bemenő paramétere. És a visszatérítési értéke az objektumok állapota ha legalább egy jelzett objektumunk van vagy a várakozási idő lejárta. Szemfor CreateSemaphore ReleaseSemaphore Mutex változó inicializásás
Számítógép-hálózatok: Labor 7 HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, // mutató a biztonsági tulajdonságokra BOOL bInitialOwner, //Mutatja hogy a mutex változó a szál tulajdona vagy sem LPCTSTR lpName //mutató a mutex változó nevére ); Hiba esetén a függvény NULL-t térít vissza másképp a mutex kezelőjét.
lezárás
WaitForSingleObject(hMutex, INFINITE); nyitás ReleaseMutex(HANDLE hMutex);
megsemmisítése a mutex változónak CloseHandle(hMutex);
Kritikus rész: Kritikus rész típusú változó deklarálása: CRITICAL_SECTION CritikusRészVáltozóNeve; InitializeCriticalSection((& CritikusRészVáltozóNeve); Használata: EnterCriticalSection(& CritikusRészVáltozóNeve); Kritikus rész törzse LeaveCriticalSection(& CritikusRészVáltozóNeve);
Számítógép-hálózatok: Labor 7
Feladat: 1. Hozzunk létre egy szervert amely, egy adatszórást valósít meg a kapcsolódott kliensek felé. Kérdések: 1. Szükséges-e a klienseknél több szál, ha megakarom valósítani az egyidejű írást és olvasást? Könyvészet: [1]. Florian Mircea Boian …: Programare concurenta pe platforme Unix, Windows, Java Albastra kiadó 2002