zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    vs2003无法打开或创建Web应用程序解决办法(HTTP/1.1 500server error错误处理方法)
    【宋红康学习日记1】关于环境变量设置出现的问题——找不到或无法加载主类 java
    【宋红康学习日记2】简单的语法知识
    【宋红康学习日记5】数组
    【宋红康学习日记4】流程控制
    【宋红康程序思想学习日记3】杨辉三角
    【宋红康程序思想学习日记1】运用位运算思想实现两个数的互换
    noaman日志第一条:20151024;“Hello.World”
    【宋红康学习日记3】运算符
    【宋红康程序思想学习日记4】数组简单操作
  • 原文地址:https://www.cnblogs.com/mc67/p/7484991.html
Copyright © 2011-2022 走看看