Koncept branja in pisanja je preprost, saj omogoča več niti hkrati, da pridobijo zaklepe za branje, vendar lahko hkrati pridobi le ena nit, zato se imenuje tudi deljeno ekskluzivno zaklepanje. V C# je priporočljivo uporabiti razred ReaderWriterLockSlim za dokončanje funkcije zaklepanja branja/pisanja. V nekaterih primerih je število branj objekta veliko večje od števila sprememb, in če je objekt zgolj zaklenjen z zaklepom, to vpliva na učinkovitost branja. Če se uporablja zaklep za branje-pisanje, lahko več niti bere objekt hkrati, ta pa bo blokiran le, ko je objekt zaseden z zaklepom pisanja. Preprosto povedano, ko nit preide v način branja, lahko druge niti še vedno vstopijo v način branja, če želi nit v tem trenutku vstopiti v način pisanja, jo je treba blokirati. Dokler ne izstopi način branja. Podobno, če nit preide v način pisanja, bodo druge niti blokirane, ne glede na to, ali želijo pisati ali brati. Obstajata dva načina za vstop v način pisanja/branja: EnterReadLock poskuša vstopiti v stanje zaklepanja v načinu pisanja. TryEnterReadLock(Int32) poskuša vstopiti v stanje zaklepanja v načinu branja, z možnostjo izbire celoštevilskega časovnega omejitev. EnterWriteLock poskuša vstopiti v stanje Write Mode Lock. TryEnterWriteLock(Int32) poskuša vstopiti v stanje zaklepanja v načinu pisanja, pri čemer je mogoče izbrati čas časovne omejitve. Obstajata dva načina za izhod iz načina pisanja/branja: ExitReadLock zmanjša rekurzivno število v načinu branja in zapusti način branja, ko je rezultat 0 (nič). ExitWriteLock zmanjša rekurzivno število vzorca pisanja in zapusti način pisanja, ko je rezultat 0 (nič). Tukaj je, kako jo uporabljati:
Vidite lahko, da lahko nit 3 in nit 4 istočasno vstopita v način branja, medtem ko nit 5 lahko preide v način pisanja po 5 sekundah (torej po tem, ko nitji 3 in 4 zapustita zaklepanje branja). Spremenite zgornjo kodo, najprej odprite 2 niti v načinu pisanja, nato pa odprite niti v načinu branja, koda je naslednja:
Rezultati so naslednji:
Kot vidite, nit 3 in nit 4 vstopita v način pisanja, vendar nit 3 najprej zasede zaklep pisanja, zato mora nit 4 počakati 10 sekund, preden vstopi. Niti 5 in 6 morata zasedati zaklep branja, zato počakajte, da nit 4 zapusti zaklep pisanja, preden nadaljujeta. TryEnterReadLock in TryEnterWriteLock lahko nastavita časovno omejitev; ko tečeta ta stavek, bo nit tukaj blokirala, če je zaklep v tem trenutku mogoče zasedeti, nato vrni true, če časovni omejitev še ni zasedel zaklepa, nato vrne false, opusti zasedbo ključavnice in nadaljuje z izvajanjem naslednje kode neposredno. VstopiUpgradeableReadLock Razred ReaderWriterLockSlim omogoča nadgradnjo načina branja, ki se razlikuje od načina branja po tem, da ga je mogoče nadgraditi v način pisanja z uporabo metod EnterWriteLock ali TryEnterWriteLock. Ker je lahko v načinu nadgradnje naenkrat le ena nit. Nit, ki vstopi v način nadgradnje, ne bo vplivala na nit v načinu branja, torej ko nit preide v način nadgradnje, lahko katerokoli število niti hkrati vstopi v način branja brez blokiranja. Če več niti že čaka na zaklepanje pisanja, bo zagon EnterUpgradeableReadLock blokiral, dokler te niti ne potečejo ali zapustijo zaklepanje pisanja. Naslednja koda prikazuje, kako nadgraditi na zapisno zaklepanje v nadgradljivem načinu branja.
Vpliv zaklepov branja/pisanja na zmogljivost je očiten. Naslednja testna koda:
Zgornja koda simulira delovanje 500 nalog, od katerih vsaka zaseda nit bazena niti, od katerih je 20 niti za pisanje, 480 pa za branje. Za branje podatkov je potrebnih 10 ms, za pisanje pa 100 ms, da se preizkusi metoda zaklepanja oziroma metoda ReaderWriterLockSlim. Za ReaderWriterLockSlim je mogoče narediti oceno, če predpostavimo, da se bere 480 niti hkrati, porabi 10 ms, 20 zapisovalnih operacij zavzame 2000ms, torej je porabljen čas 2010ms, za običajno metodo zaklepanja pa zato, ker so vse izključujoče, torej 480 bralnih operacij zavzame 4800ms + 20 zapisovalnih operacij 2000ms = 6800ms. Rezultati so pokazali opazno izboljšanje zmogljivosti.
|