Delen via


Planningsthreads

Aan elke thread is een threadprioriteit toegewezen. Threads die zijn gemaakt in de algemene taalruntime, krijgen in eerste instantie de prioriteit van ThreadPriority.Normal. Threads die buiten de runtime zijn gemaakt, behouden de prioriteit die ze hadden voordat ze de beheerde omgeving hebben ingevoerd. U kunt de prioriteit van elke thread met de Thread.Priority eigenschap ophalen of instellen.

Threads worden gepland voor uitvoering op basis van hun prioriteit. Hoewel threads worden uitgevoerd binnen de runtime, worden alle threads door het besturingssysteem toegewezen aan processortijdsegmenten. De details van het planningsalgoritmen dat wordt gebruikt om de volgorde te bepalen waarin threads worden uitgevoerd, variƫren per besturingssysteem. Onder sommige besturingssystemen wordt de thread met de hoogste prioriteit (van deze threads die kunnen worden uitgevoerd) altijd gepland om eerst te worden uitgevoerd. Als meerdere threads met dezelfde prioriteit allemaal beschikbaar zijn, doorloopt de scheduler de threads met die prioriteit, waardoor elke thread een vast tijdssegment krijgt waarin moet worden uitgevoerd. Zolang een thread met een hogere prioriteit beschikbaar is om uit te voeren, kunnen threads met een lagere prioriteit niet worden uitgevoerd. Wanneer er geen runnable threads met een bepaalde prioriteit meer zijn, wordt de planner verplaatst naar de volgende lagere prioriteit en worden de threads op die prioriteit gepland voor uitvoering. Als een thread met een hogere prioriteit wordt uitgevoerd, wordt de thread met een lagere prioriteit afgebroken en mag de thread met een hogere prioriteit opnieuw worden uitgevoerd. Bovendien kan het besturingssysteem threadprioriteiten dynamisch aanpassen als de gebruikersinterface van een toepassing wordt verplaatst tussen voorgrond en achtergrond. Andere besturingssystemen kunnen ervoor kiezen om een ander planningsalgoritmen te gebruiken.

Opmerking

Hier volgt een voorbeeld van de uitvoering van 9 threads voor alle vijf prioriteitsniveaus uit de Thread.Priority opsomming waarbij de laatste 5 zich op het hoogste prioriteitsniveau bevinden. We hebben ook callback-ondersteuning uit het vorige artikel dat in deze context laat zien dat de volgorde van thread-initialisatie en prioriteitstelling niet altijd wordt weerspiegeld in de volgende code, noch de beginvolgorde van procesuitvoeringen. Dit betekent dat we hier de parallelle aard van het uitvoeren van code en demonstratie van toegewezen processortijdsegmenten door het besturingssysteem voor elke thread zien. Dit markeert de invloed en controle van de omgeving waarin threads worden uitgevoerd. Met dat gezegd hebbende, zien we zeker dat de threads met de hoogste prioriteit inderdaad prioriteit krijgen in de uitvoering.

De volgende code produceert willekeurige resultaten voor elke uitvoering. Veelvoorkomende volgordepatronen van prioriteiten die worden uitgevoerd, kunnen echter worden waargenomen na het meerdere keren uitvoeren van de code en het analyseren van de uitvoer.

namespace snippets;

public class SchedulingThreads
{
    public void RunMultipleThreadsOnDifferentPriorities()
    {
        var threadsList = new List<Thread>(9);

        // Initialize 9 threads. 5 with Highest priority, and the first 4 from Lowest to Normal range.
        for (int i = 0; i < 9; i++)
        {
            var thread = new Thread(() => { new ThreadWithCallback(Callback).Process(); });

            if (i > 3)
                thread.Priority = ThreadPriority.Highest;
            else
                thread.Priority = (ThreadPriority)i;

            threadsList.Add(thread);
        }

        threadsList.ForEach(thread => thread.Start());
    }

    public void Callback(ThreadPriority threadPriority)
    {
        Console.WriteLine($"Callback in {threadPriority} priority. \t\t ThreadId: {Thread.CurrentThread.ManagedThreadId}.");
    }

    public class ThreadWithCallback
    {
        public ThreadWithCallback(Action<ThreadPriority> callback)
        {
            this.callback = callback;
        }

        public Action<ThreadPriority> callback;

        public void Process()
        {
            Console.WriteLine($"Entered process in {Thread.CurrentThread.Priority} priority.  \t\t ThreadId: {Thread.CurrentThread.ManagedThreadId}.");
            Thread.Sleep(1000);
            Console.WriteLine($"Finished process in {Thread.CurrentThread.Priority} priority. \t\t ThreadId: {Thread.CurrentThread.ManagedThreadId}.");

            if (callback != null)
            {
                callback(Thread.CurrentThread.Priority);
            }
        }
    }

    // The example displays the output like the following:
    //      Entered process in Highest priority.             ThreadId: 9.
    //      Entered process in Highest priority.             ThreadId: 12.
    //      Entered process in Normal priority.              ThreadId: 6.
    //      Entered process in BelowNormal priority.         ThreadId: 5.
    //      Entered process in Lowest priority.              ThreadId: 4.
    //      Entered process in AboveNormal priority.         ThreadId: 7.
    //      Entered process in Highest priority.             ThreadId: 11.
    //      Entered process in Highest priority.             ThreadId: 10.
    //      Entered process in Highest priority.             ThreadId: 8.
    //      Finished process in Highest priority.            ThreadId: 9.
    //      Finished process in Highest priority.            ThreadId: 12.
    //      Finished process in Highest priority.            ThreadId: 8.
    //      Finished process in Highest priority.            ThreadId: 10.
    //      Callback in Highest priority.                    ThreadId: 10.
    //      Finished process in AboveNormal priority.        ThreadId: 7.
    //      Callback in AboveNormal priority.                ThreadId: 7.
    //      Finished process in Lowest priority.             ThreadId: 4.
    //      Callback in Lowest priority.                     ThreadId: 4.
    //      Finished process in Normal priority.             ThreadId: 6.
    //      Callback in Highest priority.                    ThreadId: 9.
    //      Callback in Highest priority.                    ThreadId: 8.
    //      Callback in Highest priority.                    ThreadId: 12.
    //      Finished process in Highest priority.            ThreadId: 11.
    //      Callback in Highest priority.                    ThreadId: 11.
    //      Callback in Normal priority.                     ThreadId: 6.
    //      Finished process in BelowNormal priority.        ThreadId: 5.
    //      Callback in BelowNormal priority.                ThreadId: 5.
}

Zie ook