programing

.NET 내부 Hashtable에 Thread.Sleep (1)이있는 이유는 무엇입니까?

nasanasas 2020. 11. 2. 08:03
반응형

.NET 내부 Hashtable에 Thread.Sleep (1)이있는 이유는 무엇입니까?


최근에 .NET Hashtable 구현을 읽고 이해하지 못하는 코드를 발견했습니다. 코드의 일부는 다음과 같습니다.

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

전체 코드는 내 public virtual object this[object key]System.Collections.Hashtable(mscorlib의 버전 = 4.0.0.0).

질문은 ~이야:

Thread.Sleep(1)거기 있는 이유는 무엇입니까 ?


Sleep (1)은 Windows에서 프로세서를 양보하고 다른 스레드가 실행되도록하는 문서화 된 방법입니다. 주석과 함께 참조 소스에서이 코드를 찾을 수 있습니다.

   // 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 변수는 휘발성 부울입니다. 저자는 영어에 약간의 어려움이 있었다 "읽기 위반"은 "휘발성 읽기"입니다. 기본 아이디어는 양보를 피하는 것입니다. 스레드 컨텍스트 전환은 매우 비싸며 작성자가 빨리 완료되기를 바랍니다. 그것이 풀리지 않으면 CPU를 태우지 않도록 명시 적으로 양보하십시오. 이것은 아마도 오늘날 Spinlock으로 작성되었을 것이지만 Hashtable은 매우 오래되었습니다. 메모리 모델에 대한 가정도 마찬가지입니다.


나머지 구현 코드에 대한 액세스 권한이 없으면 게시 한 내용을 기반으로 교육 된 추측 만 할 수 있습니다.

즉, 메모리 또는 디스크에서 Hashtable에서 무언가를 업데이트하려고 시도하고 완료되기를 기다리는 동안 무한 루프를 수행하는 것처럼 보입니다 (를 확인하여 볼 ​​수 있음 isWriterInProgress).

단일 코어 프로세서 인 경우 한 번에 하나의 스레드 만 실행할 수 있습니다. 이와 같이 연속적인 루프에 들어가는 것은 쉽게 다른 스레드가 실행할 기회가 없다는 것을 의미 할 수 있지만 Thread.Sleep(1), 프로세서는 작성자에게 시간을 줄 기회를 제공합니다. 기다리지 않으면 작성기 스레드가 실행될 기회를 얻지 못하고 완료되지 않을 수 있습니다.


나는 소스를 읽지 않았지만 잠금없는 동시성처럼 보입니다. 해시 테이블에서 읽으려고하지만 다른 사람이 여기에 쓰고있을 수 있으므로 isWriterInProgress가 설정되지 않고 읽은 버전이 변경되지 않을 때까지 기다립니다 .

이것은 예를 들어 우리가 항상 적어도 한 번은 기다리는 이유를 설명하지 않습니다. 편집 : 그것은 우리가하지 않기 때문입니다, 그것을 지적 해 주신 @Maciej에게 감사드립니다. 경합이 없으면 즉시 진행합니다. 그래도 왜 8이 예를 들어 4 또는 16이 아닌 매직 넘버인지 모르겠습니다.

참고 URL : https://stackoverflow.com/questions/20006542/why-there-is-a-thread-sleep1-in-net-internal-hashtable

반응형