C# SpinWait
SpinWait是一种混合模式的自旋等待,被设计为先使用用户模式等待一段时间(在用户模式等待时间段内当前线程不会让出cpu的时间片),如果等待还未结束然后会切换到内核模式进行等待(这时线程会让出cpu的时间片给其他线程,会强制产生上下文调度);
SpinWait自旋等待的益处:
对于只需要短暂等待的场景,SpinWait在用户模式下就能结束等待,然后继续运行,这时线程不会因为短暂等待而发生上下文切换(因为等待的线程不会让出cpu的时间片),这样就可以提高cpu的利用率,因为有时候上下文切换所需的时间比等待的时间还要久;
对于有些确实是需要长时间等待的场景:SpinWait如果在用户模式下还没有完成等待,就会切换到内核模式进行等待,这时线程会让出cpu的时间片给其他线程,会强制触发上下文切换,这样就不会因为长时间的等待而白白占用cpu。
SpinWait使用SpinOnce方法进行一次自旋等待,我们可以通过Count属性获取SpinOnce的执行次数,同时可以通过NextSpinWillYield属性来获取下一次SpinOnce调用是否会强制上下文转换切换到内核模式进行等待;
示例:
static void Main(string[] args) { Task.Run(()=>SpinWaitMode()); Thread.Sleep(15); IsOk = true; Console.Read(); } private static bool IsOk = false; // 等待结束标志 public static void SpinWaitMode() { SpinWait spinWait = new SpinWait(); // 构造SpinWait实例 while (!IsOk) { spinWait.SpinOnce(); // 自旋等待一次 Console.WriteLine($"自旋次数:{spinWait.Count} ,下一次自旋是否会切换到内核模式等待并触发强制上下文转换:{spinWait.NextSpinWillYield}"); } Console.WriteLine("SpinWaitMode Complete"); }
运行结果: