c# spinLock 和 spinWait 基本使用

关于spinlock的基本介绍;

https://docs.microsoft.com/en-us/dotnet/standard/threading/spinlock

基本使用实例:

http://www.c-sharpcorner.com/UploadFile/1d42da/spinlock-class-in-threading-C-Sharp/

这个也是有一点难理解的呀我操;

https://msdn.microsoft.com/zh-tw/library/ee722114.aspx

https://msdn.microsoft.com/zh-tw/library/ee722116.aspx

spinwait 和 sleep的基本比较:https://www.codeproject.com/Questions/874791/Thread-Sleep-vs-Thread-SpinWait

后面我们再深入的理解一哈,先make

这里再收集一篇,关于多线程中random的使用:http://blog.csdn.net/xxdddail/article/details/16980743

关于spainWait 和 sleep 之间的一个简单比较:

http://blog.csdn.net/xxdddail/article/details/16982351

还有一篇,深度讲解额文章:

http://geekswithblogs.net/akraus1/archive/2015/06/18/165219.aspx

http://www.codeguru.com/csharp/article.php/c19283/SpinWaitSpinUntil-and-the-Task-Parallel-Library.htm

关于spinlock的基本使用法如下

var spinLock = new SpinLock (true);   // Enable owner tracking
bool lockTaken = false;
try
{
  spinLock.Enter (ref lockTaken);
  // Do stuff...
}
finally
{
  if (lockTaken) spinLock.Exit();
}

然后这个,lockTaken的由来是来自这里的啊;

spinlock 和 lock的一个对比; 在这种场景下,spanlock 花费的时间似乎更长一些; 我们后面再考虑更好测场景;

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication41
{
    class Program
    {
        //来自微软官方的实例代码;
        //To avoid this danger, CLR 4.0’s designers added the following overload to Monitor.Enter:
        //however, if you expect a significant amount of blocking, you should probably not use spin locks due to excessive spinning. Spinning can be beneficial when locks are fine-grained 


        const int N = 100000;
        static Queue<Data> _queue = new Queue<Data>();
        static object _lock = new Object();   //a shared resource is not going to be held for very long
        static  SpinLock _spinlock = new SpinLock(); //Do not store SpinLock instances in readonly fields

        //be efficient for the blocked thread to spin for a few cycles until the lock is released. By spinning
        //the thread does not become blocked, which is a CPU-intensive process
        //SpinLock should only be used after you have been determined that doing so will improve an application's performance
        //tracking thread owner


        class Data
        {
            public string Name { get; set; }
            public double Number { get; set; }
        }

        static void UpdateWithLock(Data d, int i)
        {
            lock (_lock)
            {
                _queue.Enqueue(d);
            }
        }

        private static void UpdateWithSpinLock(Data d, int i)
        {
            bool lockTaken = false; //lockTaken is false after this method if (and only if) the Enter method throws an exception and the lock was not taken
            try
            {
                _spinlock.Enter(ref lockTaken);
                _queue.Enqueue(d);

            }
            finally
            {
                if (lockTaken) _spinlock.Exit(false); //一个布尔值,该值指示是否应发出内存界定,以便将退出操作立即发布到其他线程
            }


        }

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

        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();  //用spanlock似乎话费的较长的时间;

            Console.WriteLine("Press a key");
            Console.ReadKey();

        }
    }
}

大致的结果如下:

所以,不得不说明,这是一个low-level 的应用场景滴呀;

然后我们来看另外的实例场景的使用滴呀;(信息来源:https://msdn.microsoft.com/en-us/library/system.threading.spinlock(v=vs.110).aspx)

https://docs.microsoft.com/en-us/dotnet/standard/threading/spinlock

原文地址:https://www.cnblogs.com/mc67/p/7484991.html