zoukankan      html  css  js  c++  java
  • 自旋锁-SpinLock

    自旋锁(spinlock):

    是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。

    什么情况下使用自旋锁:

    自旋锁非常有助于避免阻塞,但是如果预期有大量阻塞,由于旋转过多,您可能不应该使用自旋锁。当锁是细粒度的并且数量巨大(例如链接的列表中每个节点一个锁)时以及锁保持时间总是非常短时,旋转可能非常有帮助。

    短时间锁定的情况下,自旋锁(spinlock)更快。(因为自旋锁本质上不会让线程休眠,而是一直循环尝试对资源访问,直到可用。所以自旋锁线程被阻塞时,不进行线程上下文切换,而是空转等待。对于多核CPU而言,减少了切换线程上下文的开销,从而提高了性能。)

    SpinLock和Lock的区别:
    SpinLock,自旋锁。尝试获取该锁的线程持续不断的check是否可以获得。此时线程仍然是激活状态,只是在空转,浪费cpu而已。但是spinlock避免了线程调度和上下文切换,如果锁的时间极短的话,使用该锁反而效率会高。
    而lock是线程被block了。这将引起线程调度和上下文切换等行为。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
      
    namespace spinLock
    {
        class Program
        {
            //得到当前线程的handler
            [DllImport("kernel32.dll")]
            static extern IntPtr GetCurrentThread();
            //创建自旋锁
            private static SpinLock spin = new SpinLock();
            public static void doWork1()
            {
                bool lockTaken = false;
                try
                {
                    //申请获取锁
                    spin.Enter(ref lockTaken);
                    //下面为临界区
                    for(int i=0;i<10;++i)
                    {
                       Console.WriteLine(2);
                    }
                }
                finally
                {
                    //工作完毕,或者发生异常时,检测一下当前线程是否占有锁,如果咱有了锁释放它
                    //以避免出现死锁的情况
                    if (lockTaken)
                        spin.Exit();
                }
            }
            public static void doWork2()
            {
                bool lockTaken = false;
                try
                {
                    spin.Enter(ref lockTaken);
                    for (int i = 0; i < 10; ++i)
                    {
                        Console.WriteLine(1);
                    }
                }
                finally
                {
                    if (lockTaken)
                        spin.Exit();
                }
      
            }
            static void Main(string[] args)
            {
                Thread[] t = new Thread[2];
                t[0] = new Thread(new ThreadStart(doWork1));
                t[1] = new Thread(new ThreadStart(doWork2));
                t[0].Start();
                t[1].Start();
                t[0].Join();
                t[1].Join();
                Console.ReadKey();
            }
        }
    }
  • 相关阅读:
    JuiceSSH:安卓平台免费好用的 SSH 客户端
    git&github-本地库推送到远程库
    git&githib-给远程库取别名
    Git分支管理的本质
    MySQL学习笔记(一)--逻辑架构学习
    mysql-主从备份问题小结
    Docker--数据管理之Volumes
    初识OpenSSH--1
    一个最简单的Dockfile实践
    构词法2
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/12996693.html
Copyright © 2011-2022 走看看