Skaitymo-rašymo užraktų koncepcija yra paprasta, leidžianti kelioms gijoms vienu metu įgyti skaitymo užraktus, tačiau rašymo užraktus vienu metu galima gauti tik vienai gijai, todėl ji taip pat vadinama bendromis išskirtinėmis spynomis. C# rekomenduojama naudoti ReaderWriterLockSlim klasę, kad užbaigtumėte skaitymo / rašymo užrakto funkciją. Kai kuriais atvejais objekto skaitymų skaičius yra daug didesnis nei modifikacijų skaičius, o jei jis tiesiog užrakinamas užrakinant, tai turės įtakos skaitymo efektyvumui. Jei naudojamas skaitymo-rašymo užraktas, kelios gijos gali nuskaityti objektą vienu metu ir jis bus užblokuotas tik tada, kai objektą užims rašymo užraktas. Paprasčiau tariant, kai gija pereina į skaitymo režimą, kitos gijos vis tiek gali pereiti į skaitymo režimą, darant prielaidą, kad gija nori pereiti į rašymo režimą šiuo metu, tada ji turi būti užblokuota. kol išsijungs skaitymo režimas. Panašiai, jei gija pereina į rašymo režimą, kitos gijos bus užblokuotos, nesvarbu, ar jos nori rašyti, ar skaityti. Yra 2 būdai, kaip įjungti rašymo/skaitymo režimą: EnterReadLock bando įvesti rašymo režimo užrakto būseną. TryEnterReadLock(Int32) bando įvesti skaitymo režimo užrakto būseną su galimybe pasirinkti sveikojo skaičiaus skirtąjį laiką. EnterWriteLock bando įvesti rašymo režimo užrakto būseną. TryEnterWriteLock(Int32) bando įvesti rašymo režimo užrakto būseną ir galima pasirinkti skirtąjį laiką. Yra 2 būdai, kaip išeiti iš rašymo/skaitymo režimo: "ExitReadLock" sumažina skaitymo režimo rekursinį skaičių ir išeina iš skaitymo režimo, kai gaunamas skaičius yra 0 (nulis). "ExitWriteLock" sumažina rašymo šablono rekursinį skaičių ir išeina iš rašymo režimo, kai gautas skaičius yra 0 (nulis). Štai kaip juo naudotis:
Galite pamatyti, kad 3 ir 4 gijos gali pereiti į skaitymo režimą tuo pačiu metu, o 5 gija gali pereiti į rašymo režimą po 5 sekundžių (tai yra, po to, kai 3 ir 4 gijos išeina iš skaitymo užrakto). Pakeiskite aukščiau pateiktą kodą, pirmiausia atidarykite 2 gijas rašymo režimu, o tada atidarykite gijas skaitymo režimu, kodas yra toks:
Rezultatai yra tokie:
Kaip matote, 3 ir 4 gijos pereina į rašymo režimą, tačiau 3 gija pirmiausia užima rašymo užraktą, todėl 4 gija turi palaukti 10 sekundžių prieš įeinant. 5 ir 6 gijos turi užimti skaitymo užraktą, todėl prieš tęsdami palaukite, kol 4 gija išeis iš rašymo užrakto. "TryEnterReadLock" ir "TryEnterWriteLock" gali nustatyti skirtąjį laiką, kai bėgate prie šio sakinio, gija čia bus užblokuota, jei užraktas gali būti užimtas šiuo metu, tada grąžinkite teisingą, jei skirtasis laikas dar neužėmė užrakto, tada grąžinkite klaidingą, atsisakykite užrakto užimtumo ir toliau vykdykite šį kodą tiesiogiai. EnterUpgradeableReadLock ReaderWriterLockSlim klasė suteikia atnaujinamą skaitymo režimą, kuris skiriasi nuo skaitymo režimo tuo, kad jį taip pat galima atnaujinti į rašymo režimą iškviečiant EnterWriteLock arba TryEnterWriteLock metodus. Nes vienu metu gali būti tik viena gija atnaujinimo režimu. Gija, kuri pereina į atnaujinimo režimą, neturės įtakos gijai skaitymo režimu, tai yra, kai gija pereina į atnaujinimo režimą, bet koks skaičius gijų gali pereiti į skaitymo režimą vienu metu be blokavimo. Jei kelios gijos jau laukia, kol gaus rašymo užraktą, paleidus EnterUpgradeableReadLock bus blokuojama, kol baigsis tų gijų skirtasis laikas arba išeis iš rašymo užrakto. Šis kodas parodo, kaip atnaujinti į rašymo užraktą atnaujinamu skaitymo režimu.
Skaitymo / rašymo užraktų poveikis našumui yra akivaizdus. Šis bandymo kodas:
Aukščiau pateiktas kodas imituoja 500 užduočių veikimą, kurių kiekviena užima gijų telkinio giją, iš kurių 20 yra rašymo gijos ir 480 skaitymo gijų yra imituojamos. Norint išbandyti atitinkamai užrakto metodą ir "ReaderWriterLockSlim" metodą, reikia 10 ms nuskaityti, o rašyti - 100 ms. ReaderWriterLockSlim galima apskaičiuoti, darant prielaidą, kad 480 gijų skaitoma vienu metu, tada jis sunaudoja 10 ms, 20 rašymo operacijų užima 2000 ms, taigi sugaištas laikas yra 2010 ms, o įprastam užrakto metodui, nes jie visi yra išskirtiniai, todėl 480 skaitymo operacijų užima 4800 ms + 20 rašymo operacijų 2000 ms = 6800 ms. Rezultatai parodė pastebimą našumo pagerėjimą.
|