Junior
Ինչ է deadlock-ը?
sobes.tech AI
Պատասխան AI-ից
Դեդլոկը՝ դա մուտքի փակուղի է բազմասխալային ծրագրավորման մեջ, երբ երկու կամ ավելի թելեր միմյանց խոչընդոտում են, սպասելով ռեսուրսների, որոնք զբաղված են մյուս թելերով նույն խմբում:
Դեդլոկի առաջացման պայմանները (Կոֆման պայմաններ)
- փոխադարձ բացառություն (Mutual Exclusion): ռեսուրսները չեն կարող օգտագործվել միաժամանակ մի քանի թելերով:
- պահում և սպասում (Hold and Wait): արդեն մի ռեսուրս ունեցող թելերը սպասում են լրացուցիչ ռեսուրսի, որը զբաղեցված է այլ թելով:
- առանց նախապայման (No Preemption): ռեսուրսը չի կարող ուժեղ կերպով վերցվել այն թելից, որը նրան տիրապետում է; այն կարող է ազատվել միայն ինքնուրույն թելով:
- շրջանաձև սպասում (Circular Wait): գոյություն ունի երկու կամ ավելի թելերի շղթա, որտեղ յուրաքանչյուր թել սպասում է ռեսուրսի, որը տիրապետում է հաջորդ թելին շղթայում:
Պարզ օրինակ դեդլոկի:
երկու թել, երկու ռեսուրս (A և B):
- Թել 1-ը գրավում է ռեսուրս A-ն:
- Թել 2-ը գրավում է ռեսուրս B-ն:
- Թել 1-ը փորձում է գրավել ռեսուրս B-ն (որը զբաղեցված է Թել 2-ի կողմից):
- Թել 2-ը փորձում է գրավել ռեսուրս A-ն (որը զբաղեցված է Թել 1-ի կողմից):
Երկուսն էլ թելերը հավերժորեն փակված են:
// Պարզ օրինակ դեդլոկի սիմուլյացիայի lock օգտագործելով
object resourceA = new object();
object resourceB = new object();
void Thread1Method()
{
lock (resourceA) // Թել 1-ը գրավում է A-ն
{
Console.WriteLine("Թել 1-ը գրավեց ռեսուրս A");
Thread.Sleep(100); // Փոքր դադարեցում՝ թելերի փոխարկման ցուցադրության համար
lock (resourceB) // Թել 1-ը փորձում է գրավել B-ն
{
Console.WriteLine("Թել 1-ը գրավեց ռեսուրս B");
}
}
}
void Thread2Method()
{
lock (resourceB) // Թել 2-ը գրավում է B-ն
{
Console.WriteLine("Թել 2-ը գրավեց ռեսուրս B");
Thread.Sleep(100); // Փոքր դադար
lock (resourceA) // Թել 2-ը փորձում է գրավել A-ն
{
Console.WriteLine("Թել 2-ը գրավեց ռեսուրս A");
}
}
}
// Թելերի ստեղծում և գործարկում կարող է հանգեցնել դեդլոկի:
// new Thread(Thread1Method).Start();
// new Thread(Thread2Method).Start();
// Այս կոդի գործարկումը կարող է, բայց չի պարտադիր, ցույց տալ դեդլոկ, քանի որ կատարման կարգը կախված է պլանավորիչից:
// Եթե Թել 1-ը գրավի A-ն, իսկ Թել 2-ը՝ B-ն, նախքան առաջինը գրավի B-ն, տեղի կունենա դեդլոկ:
Դեդլոկների կանխարգելումը հաճախ հասնում է՝
- ռեսուրսների գրավման կարգը կարգավորելով (միշտ նույն կարգով գրավել ռեսուրսները):
- օգտագործելով ժամանակային սահմանափակ գրավման մեթոդներ (փորձել ռեսուրս գրավել որոշ ժամանակում):
- նախագծելով առանց միաժամանակ մի քանի բլոկավորումների պահելու անհրաժեշտության:
- օգտագործելով ագրեգատային օպերացիաներ կամ բարձր մակարդակի սինխրոնիզացիայի primitives (օրինակ,
Monitor.TryEnter,ReaderWriterLockSlim):
Դեդլոկները դժվար է հայտնաբերել, քանի որ դրանք կախված են թելերի կատարման կարգից և հաճախ հայտնվում են միայն բեռի տակ: Visual Studio-ն տրամադրում է գործիքներ դրանց հայտնաբերման և վերլուծության համար: