Kas yra lenktynių sąlyga?

Rašant daugiasluoksnes programas, viena iš dažniausiai pasitaikančių problemų yra lenktyniavimo sąlygos.

Mano klausimai bendruomenei yra šie:

Kas yra lenktynių sąlyga? Kaip jas aptinkate? Kaip su jomis elgiatės? Galiausiai, kaip užkirsti kelią jų atsiradimui?

Sprendimas

Lenktynių sąlyga atsiranda tada, kai dvi ar daugiau gijų gali pasiekti bendrus duomenis ir bando juos keisti tuo pačiu metu. Kadangi gijų planavimo algoritmas gali bet kada sukeisti gijas vietomis, nežinote, kokia tvarka gijos bandys pasiekti bendrus duomenis. Todėl duomenų keitimo rezultatas priklauso nuo gijų planavimo algoritmo, t. y. abi gijos "lenktyniauja" dėl prieigos prie duomenų ir (arba) jų keitimo.

Dažnai kyla problemų, kai viena gija atlieka "check-then-act" (pvz., "check" ar reikšmė yra X, tada "act", kad padarytų kažką, kas priklauso nuo to, ar reikšmė yra X), o kita gija kažką daro su reikšme tarp "check" ir "act". Pvz:

if (x == 5) // The "Check"
{
   y = x * 2; // The "Act"

   // If another thread changed x in between "if (x == 5)" and "y = x * 2" above,
   // y will not be equal to 10.
}

Esmė ta, kad y gali būti 10 arba bet kas, priklausomai nuo to, ar kitas siūlas pakeitė x tarp patikrinimo ir veiksmo. Jūs neturite jokios realios galimybės tai sužinoti.

Kad būtų išvengta lenktyniavimo sąlygų, paprastai bendriems duomenims uždedamas užraktas, užtikrinantis, kad vienu metu duomenis gali pasiekti tik viena gija. Tai reikštų maždaug taip:

// Obtain lock for x
if (x == 5)
{
   y = x * 2; // Now, nothing can change x until the lock is released. 
              // Therefore y = 10
}
// release lock for x
Komentarai (18)

Lenktynių sąlyga - tai tam tikra klaida, kuri atsiranda tik esant tam tikroms laiko sąlygoms.

Pavyzdys: Įsivaizduokite, kad turite dvi gijas A ir B.

Siūle A:

if( object.a != 0 )
    object.avg = total / object.a

Siūlai B:

-- kalba: c -->

object.a = 0

Jei gija A bus iš anksto užblokuota vos patikrinus, ar object.a nėra null, B atliks a = 0, o kai gija A gaus procesorių, ji atliks "dalinti iš nulio".

Tokia klaida pasitaiko tik tada, kai siūlas A yra iš anksto išskirtas iš karto po teiginio if, tai pasitaiko labai retai, bet gali atsitikti.

Komentarai (0)

Lenktynių sąlyga - tai lygiagretaus programavimo situacija, kai du lygiagretūs srautai arba procesai varžosi dėl ištekliaus, o galutinė būsena priklauso nuo to, kas pirmas gaus išteklių.

Komentarai (3)