Programavimas

Geriausia .Net gijų sinchronizavimo praktika

Sinchronizavimas yra sąvoka, naudojama siekiant užkirsti kelią kelioms gijoms tuo pačiu metu pasiekti bendrą išteklių. Galite jį naudoti, kad kelias gijas vienu metu negalėtų naudoti objekto savybių ar metodų. Viskas, ką jums reikia padaryti, tai sinchronizuoti kodo bloką, kuris pasiekia bendrą išteklių, arba sinchronizuoti skambučius į objekto ypatybes ir narius, kad bet kuriuo konkrečiu momentu tik viena gija galėtų patekti į kritinę sekciją.

Šiame straipsnyje pateikiama diskusija apie su .Net sinchronizavimu ir gijų saugumu susijusias sąvokas bei su tuo susijusią geriausią praktiką.

Išskirtinis užraktas

Išskirtinis užrakinimas naudojamas siekiant užtikrinti, kad bet kuriuo konkrečiu momentu vienas ir tik vienas siūlas galėtų patekti į kritinę sekciją. Norėdami įdiegti išskirtinius užraktus savo programoje, turite naudoti vieną iš šių būdų.

  • Užraktas - tai sintaksinis „Monitor“ klasės statinių metodų spartusis klavišas ir naudojamas norint įsigyti išskirtinį bendro šaltinio užraktą
  • „Mutex“ - panašus į užrakto raktinį žodį, išskyrus tai, kad jis gali veikti keliuose procesuose
  • „SpinLock“ - naudojamas norint įsigyti išskirtinį bendro šaltinio užraktą, išvengiant siūlų konteksto jungiklio pridėtinės vertės

Norėdami įgyvendinti siūlų saugumą savo programose, galite naudoti „Monitor“ klasės statinius metodus arba užrakto raktinį žodį. Statiški „Monitor“ klasės nariai ir užrakto raktiniai žodžiai gali būti naudojami siekiant užkirsti kelią vienalaikei prieigai prie bendro šaltinio. Užrakto raktinis žodis yra tik spartusis sinchronizavimo būdas. Tačiau, kai jums reikia atlikti sudėtingas operacijas daugialypėje programoje, „Monitor“ klasės „Wait“ () ir „Pulse“ () metodai gali būti naudingi.

Šis kodo fragmentas parodo, kaip galite įdiegti sinchronizavimą naudodami „Monitor“ klasę.

privatus statinis tik skaitomas objektas lockObj = naujas objektas ();

       static void Main (string [] args)

        {

Monitorius. Įveskite (lockObj);

                       bandyti

            {

// Kažkas kodas

            }

            pagaliau

            {

Monitorius. Išeiti (lockObj);

            }

        }

Ekvivalentiškas kodas, naudojant užrakto raktinį žodį, atrodys panašiai kaip šis:

    privatus statinis tik skaitomas objektas lockObj = naujas objektas ();

static void Main (string [] args)

        {  

bandyti

            {

užraktas (lockObj)

                {

// Kažkas kodas

                }             

            }

pagaliau

            {

// Čia galite išleisti bet kokius išteklius

            }

        }

Norėdami pasinaudoti sinchronizavimu, kuris gali apimti visus procesus, galite pasinaudoti „Mutex“ klasės pranašumais. Atkreipkite dėmesį, kad panašiai kaip užrakto sakinyje, „Mutex“ įsigytą spyną galima atleisti tik iš tos pačios gijos, kuri buvo naudojama spynai įsigyti. Spynų įsigijimas ir atleidimas naudojant „Mutex“ yra palyginti lėtesnis nei tą patį naudojant užrakto teiginį.

Pagrindinė „SpinLock“ idėja yra sumažinti išlaidas, susijusias su konteksto persijungimu tarp gijų - jei gija gali kurį laiką laukti arba suktis, kol ji galės užrakinti bendrą šaltinį, galima išvengti pridėtinės vertės, susijusios su konteksto persijungimu tarp gijų. . Kai kritinis skyrius atlieka minimalų darbą, tai gali būti geras kandidatas į „SpinLock“.

Ne išskirtinis užraktas

Norėdami apriboti sutapimą, galite pasinaudoti ne išskirtiniu užraktu. Norėdami įdiegti neišskirtinius užraktus, galite naudoti vieną iš šių būdų.

  • Semaforas - naudojamas norint apriboti gijų, kurios gali vienu metu turėti prieigą prie bendro šaltinio, skaičių. Iš esmės jis naudojamas tam tikram bendram ištekliui vienu metu riboti vartotojų skaičių.
  • „SemaphoreSlim“ - greita, lengva alternatyva „Semaforų“ klasei, kad būtų įdiegtos neišskirtinės spynos.
  • „ReaderWriterLockSlim“ - „ReaderWriterLockSlim“ klasė buvo pristatyta .Net Framework 3.5 kaip „ReaderWriterLock“ klasės pakaitalas.

Galite naudoti „ReaderWriterLockSlim“ klasę, kad įsigytumėte neišskirtinį bendro šaltinio užraktą, kurį reikėtų dažnai skaityti, bet retai atnaujinti. Taigi, vietoj abipusio išskirtinio bendro šaltinio užrakto, kurį reikia dažnai skaityti ir retai atnaujinti, galite naudoti šią klasę norėdami įsigyti skaitymo užraktą bendrame šaltinyje ir išskirtinį rašymo užraktą.

Aklavietės

Turėtumėte vengti naudoti užrakto sakinį tipui arba naudoti tokius sakinius kaip užraktas (šis), kad įdiegtumėte sinchronizavimą savo programoje, nes tai gali sukelti aklavietę. Atminkite, kad aklavietė taip pat gali atsirasti, jei ilgesnį laiką laikote užraktą, įgytą bendrame šaltinyje. Užrakto teiginiuose neturėtumėte naudoti nekintamų tipų. Pavyzdžiui, turėtumėte vengti naudoti eilutės objektą kaip raktą savo užrakto sakinyje. Turėtumėte vengti užrakto teiginio naudojimo viešo tipo - tai gera praktika užrakinti privačius ar saugomus objektus, kurie nėra internuoti. Iš esmės aklavietė susidaro, kai kelios gijos laukia viena kitos, kad atleistų bendro ištekliaus užraktą. Norėdami sužinoti daugiau apie aklavietes, galite kreiptis į šį MSDN straipsnį.

$config[zx-auto] not found$config[zx-overlay] not found