2010-04-28 6 views
6

Durum değişkenleri neden bazen hatalı olarak uyanıyor? Bazen durum değişkenleri uyanmak kendiliğinden Çünkü ben de size bir koşul değişkeni kullanan eonlardır tanıyorum

lock 
while not task_done 
    wait on condition variable 
unlock 

olduğunu. Ama neden böyle olduğunu asla anlamadım. Geçmişte okudum ki bu davranışa sahip olmayan bir durum değişkenini yapmak pahalı ama bundan daha fazlası değil.

Bu yüzden, bir koşul değişkenini beklerken yanlış bir şekilde uyandığınız için neden endişelenmeniz gerekiyor?

cevap

3

Bu durum değişkeni hatalı olarak uyanmayacaktır; koşul değişkeni sadece başka bir iş parçacığından bildirilmişse uyanır. Bununla birlikte, iş parçacığının yürütme için yeniden programlandığı zaman, başka bir iş parçacığının beklediğiniz kaynağa erişmeyi başarabilmiş olması olasıdır ve bu nedenle, iki kez kontrol etmek gerekir. Örneğin, x, y, z ipliklerinin bir grubu, daha önce tuttuğu bazı kaynak R'yi bekliyorsa ve x, y, z, w, bir koşul değişkeni üzerinden iletişim kuruyorsa ... , y, z. Yani, x, y ve z hepsi bekleme sırasından alınacak ve yürütme için planlanacak olan runqueue'a yerleştirilecektir. X'in önceden programlanmış olduğunu varsayalım, o zaman R'yi alıp, sonra uykuya dalmış olabilirsiniz, ve sonra programlanmış olabilirsiniz, bu yüzden y çalışırken, daha önce beklediğimiz R'nin hala mevcut olmadığını görebilirsiniz. , bu yüzden tekrar yatmaya gitmek için gerekli. Sonra z, uyandırır ve z ayrıca R'nin hala kullanımda olduğunu, dolayısıyla z'nin tekrar uykuya dönmesi gerektiğini bulur.

Tam olarak iki iş parçacığınız varsa ve koşul değişkeni yalnızca ikisi arasında paylaşılır. Onları, bazen bu kontrolü yapmamanın iyi olduğu durumlar vardır. Bununla birlikte, uygulamanızı dinamik hale getirmek ve rastgele sayıya kadar iş parçacığına kadar ölçeklendirme yapmak istiyorsanız, gerektiğinde bu ek kontrolü yapmak için alışkanlık haline gelmek (çok daha basit ve daha az endişe verici değil) iyidir. çoğu durum.

+0

Kontrolü gerçekleştirmemek hiçbir zaman uygun değildir. İş parçacığı uyandığında durumun yalnızca iki iş parçacığıyla bile garanti edilemeyeceği garanti edilemez. –

+1

@Nick, bu böyle değil. Durum, diğer iş parçacığının koşul değişkeniyle ilişkilendirilmiş mutex'i serbest bırakması durumunda (bu durumda, esas olarak, iki iş parçacığı arasında ileri ve geri yürütme işlemini yürütüyorsanız), o zaman güvenlidir, çünkü uyandırma ve kilitleninceye kadar kilidi yeniden alamazsınız. diğer iş parçacığı onu serbest bıraktı. Tabi ki bu işe yaramaz. –

+1

Bence yapılmaması gereken bir noktaya zorlamaya çalışıyorsunuz. Gerçekten itirazını tekrar gözden geçirmemelisin. Durum sadece iki iş parçacığıyla paylaşılsa bile, bekleyen iş parçasının sahte bir şekilde uyandığına dair garipler yoktur. –

1

Konular sinyal olmadan uyanabilirler. Bu sahte uyandırma olarak adlandırılır. Ancak, sadece nolu niçin gerçekleştikleri, batıl inanç ve belirsizlik içinde bir araya gelmiş gibi görünen bir sorudur. Gördüğüm nedenler arasında, iş parçacığı uygulamalarının çalışma şeklinin bir yan etkisi olmak ya da programlayıcıları wait koşullu koşulların yerine döngüleri düzgün bir şekilde kullanmaya zorlamak için kasıtlı olarak eklenmesi sayılabilir.

+0

LOL - "programlayıcıları beklemek yerine programlayıcıları doğru bir şekilde kullanmak için kasıtlı olarak eklenir" diye bir durum söz konusu değildir - şaka, şaka yapıyorsunuz, değil mi? :-) Değilsin! Apple'dı, değil mi? –

+0

@Bert F: Aslında sık sık POSIX'in bir programla uğraşabileceği her şekilde egzersiz yapabilecek bir Linux sürümü istemiştim. Soketler 'select'den okunabilir döner ve sonra okumak için bir şey yok. 'write', kısmi sonuçların% 50'sini döndürürdü. Durum değişkenleri kendiliğinden uyanırdı. Vb. –