Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why there is a Thread.Sleep(1) in .NET internal Hashtable?

Recently I was reading implementation of .NET Hashtable and encountered piece of code that I don't understand. Part of the code is:

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); 

The whole code is within public virtual object this[object key] of System.Collections.Hashtable (mscorlib Version=4.0.0.0).

The question is:

What is the reason of having Thread.Sleep(1) there?

like image 679
Dariusz Woźniak Avatar asked Nov 15 '13 17:11

Dariusz Woźniak


People also ask

What is the purpose of thread sleep?

Thread. sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.

Why thread sleep is not recommended?

If given a wait of 5000 Milliseconds(5 seconds) and an element just take just 1-2 seconds to load, script will still wait for another 3 seconds which is bad as it is unnecessarily increasing the execution time. So thread. sleep() increases the execution time in cases where elements are loaded in no due time.

Is thread sleep blocking?

Sleep method. Calling the Thread. Sleep method causes the current thread to immediately block for the number of milliseconds or the time interval you pass to the method, and yields the remainder of its time slice to another thread. Once that interval elapses, the sleeping thread resumes execution.

Does thread sleep create a new thread?

Java Thread Sleep important points For a quiet system, the actual time for sleep is near to the specified sleep time but for a busy system it will be little bit more. Thread sleep doesn't lose any monitors or locks current thread has acquired.


2 Answers

Sleep(1) is a documented way in Windows to yield the processor and allow other threads to run. You can find this code in the Reference Source with comments:

   // 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) ); 

The isWriterInProgress variable is a volatile bool. The author had some trouble with English "violate read" is "volatile read". The basic idea is try to avoid yielding, thread context switches are very expensive, with some hope that the writer gets done quickly. If that doesn't pan out then explicitly yield to avoid burning cpu. This would probably have been written with Spinlock today but Hashtable is very old. As are the assumptions about the memory model.

like image 98
Hans Passant Avatar answered Oct 13 '22 19:10

Hans Passant


Without having access to the rest of the implementation code, I can only make an educated guess based on what you've posted.

That said, it looks like it's trying to update something in the Hashtable, either in memory or on disk, and doing an infinite loop while waiting for it to finish (as seen by checking the isWriterInProgress).

If it's a single-core processor, it can only run the one thread at a time. Going in a continuous loop like this could easily mean the other thread doesn't have a chance to run, but the Thread.Sleep(1) gives the processor a chance to give time to the writer. Without the wait, the writer thread may never get a chance to run, and never complete.

like image 22
Tarka Avatar answered Oct 13 '22 18:10

Tarka