Çok iş parçacıklı uygulamalar yazarken en sık karşılaşılan sorunlardan biri yarış koşullarıdır.
Topluluğa sorularım şunlar:
Yarış koşulu nedir? Bunları nasıl tespit edersiniz? Nasıl ele alırsınız? Son olarak, bunların oluşmasını nasıl önlersiniz?
İki veya daha fazla iş parçacığı paylaşılan verilere erişebildiğinde ve bunları aynı anda değiştirmeye çalıştığında bir yarış koşulu oluşur. İş parçacığı zamanlama algoritması herhangi bir zamanda iş parçacıkları arasında geçiş yapabileceğinden, iş parçacıklarının paylaşılan verilere hangi sırayla erişmeye çalışacağını bilemezsiniz. Bu nedenle, verilerdeki değişikliğin sonucu iş parçacığı zamanlama algoritmasına bağlıdır, yani her iki iş parçacığı da verilere erişmek/değiştirmek için "yarışır".
Sorunlar genellikle bir iş parçacığı "check-then-act" yaptığında (örneğin "check" değer X ise, sonra "act" değerin X olmasına bağlı bir şey yapmak için) ve başka bir iş parçacığı "check" ile "act" arasında değere bir şey yaptığında ortaya çıkar. Örn:
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.
}
Mesele şu ki, y 10 olabilir veya kontrol ile hareket arasında başka bir iş parçacığının x'i değiştirip değiştirmediğine bağlı olarak herhangi bir şey olabilir. Bunu bilmenin gerçek bir yolu yok.
Yarış koşullarının oluşmasını önlemek için, aynı anda yalnızca bir iş parçacığının verilere erişebilmesini sağlamak üzere paylaşılan verilerin etrafına genellikle bir kilit koyarsınız. Bu şöyle bir anlama gelir:
// 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
Yarış koşulu, yalnızca belirli zamansal koşullarda meydana gelen bir tür hatadır.
Örnek: A ve B olmak üzere iki iş parçacığınız olduğunu düşünün.
Konu A'da:
if( object.a != 0 )
object.avg = total / object.a
Konu B'de:
object.a = 0
A iş parçacığı, object.a'nın null olmadığını kontrol ettikten hemen sonra öncelenirse, B a = 0
yapacak ve A iş parçacığı işlemciyi kazandığında, bir "sıfıra böl" yapacaktır.
Bu hata yalnızca A iş parçacığı if ifadesinden hemen sonra öncelendiğinde meydana gelir, çok nadirdir, ancak olabilir.
Yarış koşulu, eş zamanlı programlamada iki eş zamanlı iş parçacığı veya sürecin bir kaynak için yarıştığı ve ortaya çıkan son durumun kaynağı ilk kimin alacağına bağlı olduğu bir durumdur.