Kaj je tekmovalni pogoj?

Pri pisanju večnitnih aplikacij so ena najpogostejših težav tekmovalni pogoji.

Moja vprašanja za skupnost so:

Kaj je tekmovalni pogoj? Kako jih odkrijete? Kako jih obravnavate? In končno, kako preprečite, da bi se pojavila?

Rešitev

Do tekmovalnega stanja pride, ko lahko dve ali več niti dostopata do skupnih podatkov in jih poskušata hkrati spremeniti. Ker lahko algoritem za razporejanje niti kadar koli zamenja niti, ne poznate vrstnega reda, v katerem bodo niti poskušale dostopati do skupnih podatkov. Zato je rezultat spremembe podatkov odvisen od algoritma razporejanja niti, tj. obe niti "tekmujeta" za dostop do/spremembo podatkov.

Težave se pogosto pojavijo, kadar ena nit izvede postopek "check-then-act" (npr. "check" če je vrednost X, nato "act" da naredi nekaj, kar je odvisno od vrednosti X), druga nit pa med "check" in "act" nekaj naredi z vrednostjo. Npr:

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.
}

Poanta je, da je y lahko 10 ali karkoli, odvisno od tega, ali je druga nit spremenila x med preverjanjem in dejanjem. Tega ne morete vedeti.

Da bi preprečili nastanek tekmovalnih pogojev, bi navadno okoli podatkov v skupni rabi postavili ključavnico, da bi zagotovili, da lahko do podatkov hkrati dostopa le ena nit. To bi pomenilo nekaj takega:

// 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
Komentarji (18)

Tekmovalni pogoj je vrsta napake, ki se pojavi le ob določenih časovnih pogojih.

Primer: Predstavljajte si, da imate dve niti, A in B.

V niti A:

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

V navezi B:

object.a = 0

Če je nit A izločena takoj po tem, ko je preverila, da objekt.a ni nič, bo nit B izvedla a = 0, in ko bo nit A dobila procesor, bo izvedla "deljenje z nič".

Ta napaka se zgodi le, če je nit A izločena takoj po stavku if, kar je zelo redko, vendar se lahko zgodi.

Komentarji (0)

Tekmovalni pogoj je situacija v sočasnem programiranju, ko dve sočasni niti ali procesa tekmujeta za vir, končno stanje pa je odvisno od tega, kdo prej dobi vir.

Komentarji (3)