线程优先级(如何获得固定顺序) [英] Thread priority (how to get fixed order)

查看:89
本文介绍了线程优先级(如何获得固定顺序)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在控制台中,因为线程随机睡眠,它将显示线程的顺序 3,2,1或1,2,3或... 我怎样才能有固定的订单? 为什么设置优先级不会影响代码? //ThreadTester.cs //以不同的时间间隔打印多线程.

in console because threads sleep with randoms it will show the order of threads 3,2,1 or 1,2,3 or ... how can I have fixed order? and why when I set priority it doeasn't effect the code? // ThreadTester.cs // Multiple threads printing at different intervals.

    using System;
    using System.Threading;

    namespace threadTester
    {
        // class ThreadTester demonstrates basic threading concepts
        class ThreadTester
        {
            static void Main(string[] args)
            {
                // Create and name each thread. Use MessagePrinter's
                // Print method as argument to ThreadStart delegate.
                MessagePrinter printer1 = new MessagePrinter();
                Thread thread1 =
                   new Thread(new ThreadStart(printer1.Print));
                thread1.Name = "thread1";

                MessagePrinter printer2 = new MessagePrinter();
                Thread thread2 =
                   new Thread(new ThreadStart(printer2.Print));
                thread2.Name = "thread2";

                MessagePrinter printer3 = new MessagePrinter();
                Thread thread3 =
                   new Thread(new ThreadStart(printer3.Print));
                thread3.Name = "thread3";

                Console.WriteLine("Starting threads");

                // call each thread's Start method to place each 
                // thread in Started state
                thread1.Priority = ThreadPriority.Lowest;
                thread2.Priority = ThreadPriority.Normal;
                thread3.Priority = ThreadPriority.Highest;
                thread1.Start();
                thread2.Start();
                thread3.Start();

                Console.WriteLine("Threads started\n");
                Console.ReadLine();

            } // end method Main

        } // end class ThreadTester

        // Print method of this class used to control threads
        class MessagePrinter
        {
            private int sleepTime;
            private static Random random = new Random();

            // constructor to initialize a MessagePrinter object
            public MessagePrinter()
            {
                // pick random sleep time between 0 and 5 seconds
                sleepTime = random.Next(5001);
            }

            // method Print controls thread that prints messages
            public void Print()
            {
                // obtain reference to currently executing thread
                Thread current = Thread.CurrentThread;

                // put thread to sleep for sleepTime amount of time
                Console.WriteLine(
                   current.Name + " going to sleep for " + sleepTime);

                Thread.Sleep(sleepTime);

                // print thread name
                Console.WriteLine(current.Name + " done sleeping");

            } // end method Print

        } // end class MessagePrinter
    }

推荐答案

您之所以使用线程正是因为您不关心使事情按特定顺序发生,而是想要:

You use threads precisely because you do not care about having things happen in a particular order, but want either:

  1. 与此同时,如果有足够的内核允许它们一起发生.
  2. 有些人在进步,而另一些人在等待某事.
  3. 交错处理,注意I/O或用户输入,以便继续响应.

在每种情况下,您都不必担心自己不知道什么时候会发生什么.

In each of these cases, you just don't care that you don't know just which bit of what will happen when.

但是:

  1. 您可能仍然会关心某些序列的顺序.在最简单的情况下,只需让这些事情在同一线程中依次发生,而其他事情在其他线程中发生.通过将任务链接在一起,可以处理更复杂的情况.
  2. 您可能希望最终将来自不同线程的结果放在不同的顺序中.最简单的方法是在它们全部完成之后将它们全部排序,尽管您也可以在它们来时对结果进行排序(虽然有点棘手).

为了获得理想的性能,每个时刻都应该在每个内核上运行一个线程(或者在超线程内核上可能运行两个线程,但这会带来更多的复杂性).假设您有一台具有4个核心和8个任务的机器.

For ideal performance, there should be one thread running on each core (or possibly two on a hyperthreaded core, but that has further complications) at all times. Let's say you have a machine with 4 cores and 8 tasks you need done.

如果任务涉及大量等待I/O的任务,那么将开始四个任务,每个任务都将达到等待该I/O的地步,并允许其他任务之一取得一些进展.很有可能即使任务数是内核数的两倍,它最终仍将有大量空闲时间.如果每个任务要花费20秒,那么在不同的线程上执行它们可能会使它们都在20秒多一点的时间内完成,因为所有这些都将20秒的大部分时间都花在等待其他事情上.

If the tasks involved a lot of waiting on I/O, then four will start, each will reach a point where it's waiting on that I/O, and allow one of the other tasks to make some progress. Chances are that even with the number of tasks being twice the number of cores, it'll still end up with plenty of idle time. If each task was going to take 20seconds, then doing them on different threads will probably have them all done in just a little over 20seconds, since all of them were spending most of their 20seconds waiting on something else.

如果您要执行使CPU一直忙碌的任务(没有太多等待内存,当然也没有I/O),那么您一次可以执行四个这样的任务,而其他任务正在等待让他们要么完成,要么放弃自己的时间.在这里,如果每个时间花费20秒,那么您所希望的最好的总时间是大约40秒(并且假设系统上任何进程的其他线程都没有想要CPU的情况,那么您在设置CPU时就完全没有开销了)线程等).

If you are doing tasks that keep the CPU busy all the time (not much waiting for memory and certainly not for I/O) then you will be able to have four such tasks going at a time, while the others are waiting for them to either finish, or give up their slice of time. Here if each took 20seconds, the best you could hope for is a total time of about 40seconds (and that's assuming that no other thread from any process on the system wants the CPU, that you've a perfect lack of overhead in setting up the threads, etc).

如果要完成的工作(核心工作要做,而不是等待I/O完成,另一个线程释放锁等)而不是内核,则OS调度程序将在不同线程之间交换想要活跃.确切的细节因操作系统而异(不同的Windows版本,包括台式机和服务器设置之间的一些重要差异,采用不同的方法,不同的Linux版本以及从2.4到2.6的特别大的更改以及不同的Unix等)都具有不同的策略).

In cases where there is more work to do (active work to do, rather than waiting for I/O to complete, another thread to release a lock, etc.) than cores, the OSs scheduler will swap around between different threads that want to be active. The exact details differs from OS to OS (different Windows versions, including some important differences between desktop and server set ups, take different approaches, different Linux versions with some particularly big changes from 2.4 to 2.6 and different Unixes, etc. all have different strategies).

他们共有的一件事是确保完成任务的共同目标.

One thing they all have in common is the common goal of making sure stuff gets done.

线程优先级和进程优先级是影响此调度的方法.使用Windows,每当有更多线程在等待工作而不是核心在工作时,那些优先级最高的线程将以循环方式获得给定的CPU时间.如果没有该优先级的线程,那么将给倒数第二个线程分配CPU时间,然后分配下一个,依此类推.

Thread priorities and process priorities are ways to influence this scheduling. With Windows, whenever there's more threads waiting to work than cores to work, those of the highest priority get given CPU time in a round-robin fashion. Should there be no threads of that priority, then those of the next lowest are given CPU time, then the next and so on.

这是使事物停止运转的好方法.当一个被赋予高优先级的线程(大概是因为它的工作被认为是至关重要的)正在等待一个被给与低优先级的线程(可能是因为它的工作被认为不那么重要,并且人们希望它总是将时间分配给它)时,这可能导致复杂化.其他优先级),并且低优先级线程不会一直被分配CPU时间,因为总是有比可用内核更高优先级的线程.因此,所谓的高优先级线程根本没有CPU时间.

This is a great way to have things grind things to a halt. It can lead to complications where a thread that was given high priority (presumably because it's work is considered particularly crucial) is waiting on a thread given low priority (presumably because its work is considered less important and one wants it to always cede time to the others), and the low-priority thread keeps not being given CPU time, because there's always more threads of higher priority than available cores. Hence the supposedly high-priority thread gets no CPU time at all.

为解决此问题,Windows有时会提升长时间未运行的线程.这可以解决问题,但是现在意味着您应该拥有超高优先级的低优先级线程,这不仅损害了应用程序的其余部分,而且损害了系统的其余部分.

To fix this situation, windows will occasionally promote the threads that haven't run in a long time. This fixes things, but now means you've got the supposedly low-priority threads bursting along as super-high priority to the detriment not just of the rest of the application but also the rest of the sytem.

(拥有多核系统的最好的事情之一是,这意味着您的计算体验受设置线程优先级的人员的影响较小!)

(One of the best things about having a multi-core system, is it means your computing experience is less affected by people who set the priority of threads!)

如果使用调试器停止多线程.NET应用程序并检查线程,则您可能会发现所有线程均正常,除了最高的线程除外.最高级别的终结器将是终结器线程,并且它以最高优先级运行是其重要的原因之一,即终结器不应花很长时间执行-以最高优先级完成工作是一件坏事,尽管这样做是合理的在这种情况下,必须尽快结束.

If you use a debugger to stop a multi-threaded .NET application and examine the threads you'll probably find that all of them are at normal except for one at highest. This one at highest will be the finalizer thread and its running at highest priority is one of the reasons its important that finalizers should not take a long time to execute - having work done at highest priority is a bad thing and while it is justified in this case, it must end as soon as possible.

在所有其他情况下,至少有95%的情况是有人设置了线程的优先级,这是一个逻辑错误-大多数情况下,它不会执行任何操作,并使其余的事情变得一团糟.它们可以很好地使用(或者根本不具备这种能力),但是绝对应该将它们放在高级技术"类别中. (我喜欢把自己的空闲时间花在尝试多线程技术上,这些技术在大多数时候通常被认为是过分的和过早的优化,而我仍然很少碰到优先事项.)

At least 95% of all other cases where someone sets the priority of a thread is a logical bug - it'll do nothing most of the time and allows things to get very messed up the rest. They can be used well (or we wouldn't have that ability at all), but should definitely be put in the "advanced techniques" category. (I like to spend my free time experimenting with multi-threading techniques that would count as excessive and premature optimisation most of the time, and I still hardly ever touch priorities).

在您的示例中,优先级的影响很小,因为每个线程大部分时间都在睡眠,所以无论哪个线程想要CPU时间,都可以在需要运行的纳秒时间内获得它.但是,如果您在内核也忙于其他普通线程的机器上运行它,那么整个事情就会变得不必要地变慢.在这种情况下,thead1最初不会获得任何CPU时间(因为总是有更高优先级的线程需要CPU),然后在3秒后,调度程序就会意识到它永远饿死了CPU速度(90亿个CPU)周期左右),并使其具有最高优先级的爆发时间足够长,以使其与重要的Windows服务的时间保持一致!幸运的是,它随后进入睡眠状态,然后完成一分钟的工作,因此不会造成任何危害,但是,如果它确实在做任何事情,则可能会对整个系统的性能产生某些令人讨厌的影响.

In your example, priority will have little effect because each thread spends most of its time sleeping, so whichever thread does want CPU time can get it for the few nano-seconds it needs to run. What it could do though is cause the whole thing to become needlessly slower should you run it on a machine where the cores are also busy with other normal threads. In this case thead1 wouldn't get any CPU time at first (because there's always a higher priority thread that wants the CPU), then after 3seconds the scheduler would realise its been starved for an eternity the terms of CPU speeds (9billion CPU cycles or so) and give it a burst to highest priority for long enough to let it screw with the timing of vital windows services! Luckily it then sleeps and then does a minute amount of work before finishing, so it does no harm, but if it was doing anything real it could have some really nasty effects on the entire system's performance.

这篇关于线程优先级(如何获得固定顺序)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆