C#、线程优先级和锁

use*_*126 3 c# multithreading locking preemption

在 C# 中,如果一个高优先级任务已准备好执行,而另一个(低优先级)线程已在监视器内,则在以下两种情况下,低优先级任务是否会被抢占:

  1. 较高优先级任务想要获取由低优先级任务获取的一个(或多个)锁。
  2. 高优先级任务不需要低优先级任务获取的任何锁。

编译器/操作系统在任务抢占方面是否做了任何聪明的事情,或者总是出现较高优先级任务总是抢占较低优先级任务的情况?

use*_*126 6

对于那些对问题的第一种情况感兴趣的人,以下是我在处理锁定时测试线程抢占所做的实验:

object resourselock = new object();

    public void Test()
    {
        Thread lowestThread = new Thread(new ThreadStart(Low));
        lowestThread.Priority = ThreadPriority.Lowest;

        Thread highestThread = new Thread(new ThreadStart(High));
        highestThread.Priority = ThreadPriority.Highest;

        lowestThread.Start();
        Thread.Sleep(1000);   //makes sure that the lowest priority thread starts first
        highestThread.Start();
    }

    
    public void Low()
    {
        Console.WriteLine("Low priority task executed");

        lock (resourselock)
        {
            Console.WriteLine("Low priority task will never release the lock!");

            while (true) ; //infinite empty statement!
        }
    }

    public void High()
    {
        System.Console.WriteLine("High priority task executed");

        lock (resourselock)
        {
            System.Console.WriteLine("High priority task got the lock!"); //this will never be reached!
        }
    }
Run Code Online (Sandbox Code Playgroud)

以下是程序的输出:

执行低优先级任务

低优先级任务永远不会释放锁!

高优先级任务执行

虽然高优先级任务需要获取资源锁(低优先级任务已经获取了)才能执行,但是高优先级任务执行完却发现它无法执行!因此,当任务需要资源执行时,编译器不会进行任何优化来防止不必要的上下文切换。