• SpinLock(自旋锁)


    SpinLock(自旋锁)

    SpinLock 结构是一个低级别的互斥同步基元,它在等待获取锁时进行旋转。 在多核计算机上,当等待时间预计较短且极少出现争用情况时,SpinLock 的性能将高于其他类型的锁。 不过,仅在通过分析确定 System.Threading.Monitor 方法或 Interlocked 方法显著降低了程序的性能时使用 SpinLock。

    System.Threading.SpinLock 是一个低级别的互斥锁,可用于等待时间非常短的场合SpinLock 不是可重入的。 在线程进入锁之后,它必须先正确地退出锁,然后才能再次进入锁。 通常,任何重新进入锁的尝试都会导致死锁,并且死锁非常难调试。 作为开发的辅助手段,System.Threading.SpinLock 支持一种线程跟踪模式,当线程尝试重新进入它已经持有的锁时,此模式将会导致引发异常。 这将让您更易于定位到锁未正确退出的点。 通过使用一个采用布尔输入形参的 SpinLock 构造函数并传入 true 实参,可以启用线程跟踪模式。 完成开发和测试阶段之后,应关闭线程跟踪模式以获得更好的性能。

    使用SpinLock的Demo:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace MyConsole2
    {
        class Program
        {
            const int N = 10000;
            static Queue<Data> _queue = new Queue<Data>();
            static object _lock = new object();
            static SpinLock _spinlock = new SpinLock();
            class Data
            {
                public string Name { get; set; }
                public double Number { get; set; }
            }
    
            static void UpdateWithSpinLock(Data d, int i)
            {
                bool lockTaken = false;
                try
                {
                    _spinlock.Enter(ref lockTaken);
                    _queue.Enqueue(d);
                }
                finally
                {
                    if (lockTaken) _spinlock.Exit(false);
                }
                 
            }
    
            static void UseSpinLock()
            {
                Stopwatch sw = Stopwatch.StartNew();
    
                Parallel.Invoke(()=> {
                    for (int i = 0; i < N; i++)
                    {
                        UpdateWithSpinLock(new Data() { Name = i.ToString(), Number = i }, i);
                    }
                },
                ()=> {
                    for (int i = 0; i < N; i++)
                    {
                        UpdateWithSpinLock(new Data() { Name = i.ToString(), Number = i }, i);
                    }
                });
    
                sw.Stop();
                Console.WriteLine("elapsed ms with spinlock: {0}", sw.ElapsedMilliseconds);
    
            }
    
            static void UpdateWithLock(Data d, int i)
            {
                lock (_lock)
                {
                    _queue.Enqueue(d);
                }
            }
    
            private static void UseLock()
            {
                Stopwatch sw = Stopwatch.StartNew();
    
                Parallel.Invoke(
                        () => {
                            for (int i = 0; i < N; i++)
                            {
                                UpdateWithLock(new Data() { Name = i.ToString(), Number = i }, i);
                            }
                        },
                        () => {
                            for (int i = 0; i < N; i++)
                            {
                                UpdateWithLock(new Data() { Name = i.ToString(), Number = i }, i);
                            }
                        }
                    );
                sw.Stop();
                Console.WriteLine("elapsed ms with lock: {0}", sw.ElapsedMilliseconds);
            }
            static void Main(string[] args)
            {
                UseLock();
                _queue.Clear();
                UseSpinLock();
    
                Console.ReadLine();
            }        
    
        }
    
    }
  • 相关阅读:
    需求工程阅读笔记03
    需求工程阅读笔记02
    【Augmented Reality】增强现实中的光学透射式头盔显示器的标定进阶
    基于单个RGB摄像头的手势识别程序设计与实现
    将Vuforia程序发布到Windows10系统的基本流程
    基于Unity3D 的Vuforia SDK开发基础教程
    微软KinectV2深度传感器在Ubuntu上的配置和使用
    Windows 10(64位)配置Caffe运行环境的基本流程
    Ubuntu14.04 64位配置Caffe 教程(基于CUDA7.5)
    空间增强现实——基于贝塞尔曲面的异形表面投影变形技术
  • 原文地址:https://www.cnblogs.com/goodlucklzq/p/4488105.html
Copyright © 2020-2023  润新知