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

运行结果:

 

posted @ 2021-01-01 17:46  温故纳新  阅读(2093)  评论(0编辑  收藏  举报