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
相关产品推荐
相关产品推荐

