2013-11-15 14 views
70

Geçtiğimiz günlerde .NET Hashtable'un uygulanmasını okudum ve anlamadığım bir kod parçasıyla karşılaştım. kodunun bir parçasıdır:Neden .NET iç Hashtable'da bir Thread.Sleep (1) var?

int num3 = 0; 
int num4; 
do 
{ 
    num4 = this.version; 
    bucket = bucketArray[index]; 
    if (++num3 % 8 == 0) 
    Thread.Sleep(1); 
} 
while (this.isWriterInProgress || num4 != this.version); 

tüm kod System.Collections.Hashtable arasında public virtual object this[object key] (mscorlib Version = 4.0.0.0) içindedir.

soru şudur:

orada Thread.Sleep(1) olmasının sebebi nedir?

+7

Bir içerik anahtarından önce bir spinwait gibi görünüyor. Yani İpliği uyumadan önce 8 kez bir koşulu kontrol eder. – Groo

+4

[Benzer konu] (http://stackoverflow.com/questions/508208/what-is-the-impact-of-thread-sleep1-in-c); Crux, OS'nin başka bir görevi zamanlamasına izin vermektir – Konstantin

cevap

70

İşlemciyi vermek ve diğer iş parçacıklarının çalışmasına izin vermek için uyku (1) Windows'ta belgelenmiş bir yöntemdir. Yorumlarla Referans Kaynak Bu kodu bulabilirsiniz:

// Our memory model guarantee if we pick up the change in bucket from another processor, 
    // we will see the 'isWriterProgress' flag to be true or 'version' is changed in the reader. 
    // 
    int spinCount = 0; 
    do { 
     // this is violate read, following memory accesses can not be moved ahead of it. 
     currentversion = version; 
     b = lbuckets[bucketNumber]; 

     // The contention between reader and writer shouldn't happen frequently. 
     // But just in case this will burn CPU, yield the control of CPU if we spinned a few times. 
     // 8 is just a random number I pick. 
     if((++spinCount) % 8 == 0) { 
      Thread.Sleep(1); // 1 means we are yeilding control to all threads, including low-priority ones. 
     } 
    } while (isWriterInProgress || (currentversion != version)); 

isWriterInProgress değişken uçucu bir bool. Yazarın İngilizcede "ihmal okuma" ile ilgili bir sorun vardı "uçucu okundu". Temel fikir verimden kaçınmaya çalışmaktır, konu bağlam anahtarları çok pahalıdır ve yazarın çabucak bitirilmesi umudunu taşımaktadır. Bu tava dışarı çıkmazsa, cpu'nun yanmasını önlemek için açık bir şekilde verim verir. Bu muhtemelen bugün Spinlock ile yazılmıştır, ancak Hashtable çok eskidir. Bellek modeli ile ilgili varsayımlar gibi.

+7

Sadece bir verim istiyorsanız Sleep (0) 'dır diye düşündüm. 'Uyku (1)' aslında bir uykudır. –

+11

Uyku (0) yalnızca daha yüksek önceliğe sahip çalışmaya hazır başka bir iş parçacığı varsa verilir. Buradaki niyet değil. –

+0

Sadece eşit öncelikli iş parçacıkları aslında ... hangi verim genellikle anlamına gelir. –

5

Kaynağı okumadım ama kilitsiz bir eşzamanlılık gibi görünüyor. Hashtabından okumaya çalışıyorsunuz, ama başka biri ona yazıyor olabilir, bu yüzden isWriterInProgress unsetini beklemeniz ve okuduğunuz sürümün değişmediğini unutmayın. Bu neden olduğunu açıklamıyor örn. hep en az bir kez bekleriz. DÜZENLEME: çünkü biz bunu yapmadığın için teşekkürler @Maciej. Çekişme olmadığında hemen devam ederiz. 8'in neden sihirli numara olduğunu bilmiyorum. Yine de 4 veya 16.

+3

Hayır, yapmayız. '++ num3 'sonra' num3' 1 olacaktır. Ya da ciddi derecede kafeinden yoksundur. –

+0

@MaciejStachowski oops, iyi yakalama, yanlış okumuş. –

+0

Uyku, yalnızca bir yazıcının devam ettiği veya sürümün yanlış olduğu 8 ardışık yineleme sonrasında yapılır. Muhtemelen, yazarın işini yapması için bir şans vermek. – dan04

7

Uygulama kodunun geri kalanına erişiminiz olmadığında, yalnızca yayınladığınız bilgilere dayalı olarak eğitimli tahminler yapabilirim.

Bu, Hashtable'da, bellekte veya diskte bir şeyi güncellemeye çalıştığı ve bitmesini beklerken sonsuz bir döngü gerçekleştirdiği görülüyor (isWriterInProgress'u denetleyerek görüldüğü gibi).

Tek çekirdekli bir işlemci ise, yalnızca tek bir iş parçacığını aynı anda çalıştırabilir. Böyle sürekli bir döngüde gitmek, diğer iş parçacığının çalışma şansının olmaması anlamına gelebilir, ancak Thread.Sleep(1), işlemciye yazıcıya zaman kazandırma şansı verir. Beklemeden yazarın yazarı asla koşma şansı bulamaz ve asla tamamlamaz.