C# SpinLock用法。

Posted yeqifeng2288

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# SpinLock用法。相关的知识,希望对你有一定的参考价值。

 class Program
    
        static void Main(string[] args)
        
            var count = 0;
            var taskList = new Task[10];
            Stopwatch sp = new Stopwatch();
            sp.Start();

            // 不要意外复制。每个实例都是独立的。
            SpinLock _spinLock = new SpinLock();
            for (int i = 0; i < taskList.Length; i++)
            
                taskList[i] = Task.Run(() =>
                
                    bool _lock = false;
                    for (int j = 0; j < 10_000_000; j++)
                    
                        _spinLock.Enter(ref _lock);
                        count++;
                        _spinLock.Exit();
                        _lock = false;
                    
                );
            

            sp.Stop();
            Task.WaitAll(taskList);
            Console.WriteLine($"完成! 耗时:sp.ElapsedTicks");
            Console.WriteLine($"结果:count");
        
    

微软文档:  https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.spinlock?redirectedfrom=MSDN&view=netframework-4.8#code-snippet-2p%23code-snippet-2

注解

有关如何使用旋转锁定的示例, 请参阅如何:使用旋转锁进行低级别同步

自旋锁可用于叶级锁, 在这种情况Monitor下, 通过使用、大小或由于垃圾回收压力而隐含的对象分配的成本非常高。 旋转锁定有助于避免阻塞;但是, 如果你预计会有大量的阻塞, 则可能由于旋转过多而无法使用自旋锁。 当锁的粒度较大且数值较大 (例如, 链接列表中的每个节点都有一个锁) 以及锁保留时间始终极短时, 旋转可能非常有利。 通常, 在持有自旋锁时, 应避免使用以下任何操作:

  • 堵塞

  • 调用自身可能会阻止的任何内容,

  • 同时保留多个自旋锁,

  • 进行动态调度的调用 (interface 和虚方法),

  • 对任何代码进行静态调度调用, 而不是任何代码, 或

  • 分配内存。

SpinLock仅应在确定这样做后使用才能改善应用程序的性能。 出于性能方面的考虑, 还SpinLock必须注意, 是值类型。 出于此原因, 必须注意不要意外复制SpinLock实例, 因为两个实例 (原始和副本) 将完全独立, 这可能会导致应用程序出现错误的行为。 如果必须传递实例, 则它应按引用而不是按值传递。 SpinLock

不要在只读SpinLock字段中存储实例。

以上是关于C# SpinLock用法。的主要内容,如果未能解决你的问题,请参考以下文章

Linux中的spinlock机制 - CAS和ticket spinlock

spinlock

Linux内核源码分析 -- 同步原语 -- 自旋锁 spinlock

Linux内核源码分析 -- 同步原语 -- 自旋锁 spinlock

深入分析_linux_spinlock_实现机制

Linux内核自旋锁spinlock_t机制