C#、线程优先级和锁

本文关键字:优先级 线程 | 更新日期: 2023-09-27 18:32:38

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

    优先级
  1. 较高的任务想要获取由低优先级任务获取的一个(或多个(锁。
  2. 优先级
  3. 较高的任务不需要低优先级任务获取的任何锁。
编译器/操作系统在任务抢占

方面是否做了任何聪明的事情,或者是否总是高优先级任务总是抢占低优先级的任务?

C#、线程优先级和锁

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

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!
        }
    }

以下是程序的输出:

执行的低优先级任务

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

执行高优先级任务

尽管高优先级任务

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

如果优先级较高的线程正在等待锁,则无论哪个线程拥有锁,都不会计划它。

如果优先级较高的线程没有等待任何内容,则它可能会抢占优先级较低的线程。不过,这些都不是真正特定于 .NET 或 C# 的 - 它最终归结为操作系统来管理线程并调度它们。

您可能会发现这篇关于线程优先级的 MSDN 文章很有用 - 它确实让我在几点上感到惊讶。特别:

系统以轮循机制方式将时间片分配给具有最高优先级的所有线程。如果这些线程都没有准备好运行,则系统会以轮循机制方式将时间片分配给优先级次高的所有线程。如果优先级较高的线程可供运行,系统将停止执行优先级较低的线程(不允许它完成其时间片的使用(,并将完整时间片分配给优先级较高的线程。

您应该能够通过创建一个程序来验证一些高优先级线程和一些低优先级线程;上面的引用表明,如果您可以让处理器忙于高优先级线程,那么低优先级线程将完全饿死。这让我感到惊讶,但你应该能够尝试一下,看看会发生什么。只需尝试让高优先级线程忙于不会导致任何 IO(等(的工作,否则会使它们停止。