最近我在读《实现》.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);

整个代码在System.Collections.Hashtablepublic virtual object this[object key]以内(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变量是易失性布尔值.笔者在英语中遇到了一些麻烦,"违规阅读"是"易失性阅读".基本的 idea 是尽量避免让步,线程上下文切换是非常昂贵的,希望作者能尽快完成.如果这不起作用,那么显式让步以避免消耗CPU.这可能是今天用Spinlock写的,但是Hashtable已经很旧了.关于内存模型的假设也是如此.

.net相关问答推荐

如何使用AWS Lambda函数制作网络挂钩?

CustomControl 计算自己的宽度和高度 - 使用 bounds.Height=0 调用 ArrangeOverride

在接口内部声明 IEnumerable 而在具体类中声明 IList

MongoDB GridFs with C#,如何存储图片等文件?

关于在 .NET 中干净地终止线程的问题

将 Moq 模拟对象传递给构造函数

是否可以像 WebView 一样在 Windows 窗体中嵌入 Gecko 或 Webkit?

来自奥尔森时区的 .NET TimeZoneInfo

泛型方法是如何、何时、何地具体化的?

IEnumerable Count() 和 Length 的区别

有什么方法可以在不重新编译的情况下覆盖 .NET Windows 服务名称?

将双精度转换为带有 N 个小数的字符串,点作为小数分隔符,并且没有千位分隔符

C# 属性实际上是方法吗?

C# 编译为 32/64 位,或任何 cpu?

如何保护我的 .NET 程序集免受反编译?

为什么甚至可以更改私有成员,或使用反射在 C# 中运行私有方法?

我可以将构造函数参数传递给 Unity 的 Resolve() 方法吗?

如何使用 XmlSerializer 将字符串序列化为 CDATA?

枚举和匹配属性的 C# 命名约定

SqlParameter 已被另一个 SqlParameterCollection 包含 - using() {} 作弊吗?