You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中for循环创建多线程:为何后启动线程先获取Mutex锁?

线程启动顺序与Mutex锁获取顺序的疑问

问题代码

internal class Program
{
    static Mutex mutex = new Mutex();
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i++)
        {
            Thread t1 = new Thread(AcquireMutex);
            t1.Name = string.Format("Thread{0}", i + 1);
            t1.Start();
        }
        
    }

    private static void AcquireMutex(object? obj)
    {
        mutex.WaitOne();
        DoSomething();
        mutex.ReleaseMutex();
        Console.WriteLine("Mutex released by {0}", Thread.CurrentThread.Name);
    }

    private static void DoSomething()
    {
        Thread.Sleep(1000);
        Console.WriteLine("Mutex acquired by {0}", Thread.CurrentThread.Name);
    }
}

疑问

我原本认为for循环会先启动Thread1,再依次启动后续线程,但运行代码时发现有时Thread10会比Thread1先获取Mutex锁。想请教:为何按顺序启动的线程中,后启动的线程能先获取锁?


解答

  • 线程启动不等于立即执行:调用Thread.Start()只是向操作系统提交了线程的执行请求,线程何时真正开始运行由操作系统的线程调度器决定。调度器会根据当前CPU的负载、线程优先级等动态分配执行时间片,后启动的线程完全可能被优先调度到CPU上执行。

  • Mutex无严格FIFO等待队列保证:虽然Mutex通常会遵循“先到先得”的逻辑,但它并没有严格保证等待线程的锁获取顺序是先进先出(FIFO)。操作系统的调度机制可能会根据实际情况调整锁的分配,比如优先让优先级更高的线程获取锁,或是为了调度效率做出的优化。

  • 线程启动流程存在时间差:创建线程并调用Start()的过程本身需要消耗一定时间。当循环快速创建10个线程时,Thread10可能在Thread1还未完成启动流程、尚未进入mutex.WaitOne()的等待状态时,就已经完成启动并开始尝试获取锁,自然能先拿到锁。

内容的提问来源于stack exchange,提问作者Subin Suthan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 01:46:11