为什么Spinlock不支持递归

发布于 2025-01-18 13:13:24 字数 1401 浏览 0 评论 0原文

我想知道为什么 SpinLock 不支持递归。

假设我有一个带有 Monitor 的简单程序,它以递归方式锁定和释放指令块:

class Program
{
    private static readonly object lockObj = new object();

    private static void Recursion(int x)
    {
        bool lockWasTaken = false;
        try
        {
            Monitor.Enter(lockObj, ref lockWasTaken);
            Console.WriteLine(x);
        }
        finally
        {
            if (x > 0)
            {
                Recursion(x - 1);
            }
            if (lockWasTaken) Monitor.Exit(lockObj);
        }
    }

    static void Main(string[] args)
    {
        Recursion(5);

        Console.ReadKey();
    }
}

如果我对 SpinLock 执行相同操作:

class Program
{
    private static SpinLock sl = new SpinLock(true);

    private static void Recursion(int x)
    {
        bool lockWasTaken = false;
        try
        {
            sl.Enter(ref lockWasTaken);
            Console.WriteLine(x);
        }
        finally
        {
            if (x > 0)
            {
                Recursion(x - 1);
            }
            if (lockWasTaken) sl.Exit();
        }
    }

    static void Main(string[] args)
    {
        Recursion(5);

        Console.ReadKey();
    }
}

它会抛出一个异常,表示调用线程已经拥有锁——这显然是真的。 但我的问题是为什么 Monitor 可以通过同一线程多次获取锁,而 SpinLock 却不能? 我找不到任何原因说明已经锁定关键部分的线程无法再次进入它。

I wonder why SpinLock doesn't support recursion.

Let's say I have a simple program with Monitor that locks and releases a block of instructions in a recursive way:

class Program
{
    private static readonly object lockObj = new object();

    private static void Recursion(int x)
    {
        bool lockWasTaken = false;
        try
        {
            Monitor.Enter(lockObj, ref lockWasTaken);
            Console.WriteLine(x);
        }
        finally
        {
            if (x > 0)
            {
                Recursion(x - 1);
            }
            if (lockWasTaken) Monitor.Exit(lockObj);
        }
    }

    static void Main(string[] args)
    {
        Recursion(5);

        Console.ReadKey();
    }
}

If I do the same with SpinLock:

class Program
{
    private static SpinLock sl = new SpinLock(true);

    private static void Recursion(int x)
    {
        bool lockWasTaken = false;
        try
        {
            sl.Enter(ref lockWasTaken);
            Console.WriteLine(x);
        }
        finally
        {
            if (x > 0)
            {
                Recursion(x - 1);
            }
            if (lockWasTaken) sl.Exit();
        }
    }

    static void Main(string[] args)
    {
        Recursion(5);

        Console.ReadKey();
    }
}

It throws an excpetion which says the calling thread already has a lock - and it is obviously true.
But my question is why Monitor can acquire a lock multiple times by the same thread while SpinLock cannot?
I can't find any reasons why a thread that has already locked a critical section can't enter it again.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文