Dela via


Schemaläggning av trådar

Varje tråd har tilldelats en trådprioritet. Trådar som skapas inom den vanliga språkkörningen tilldelas ursprungligen prioriteten ThreadPriority.Normalför . Trådar som skapats utanför körningen behåller den prioritet de hade innan de gick in i den hanterade miljön. Du kan hämta eller ange prioriteten för valfri tråd med egenskapen Thread.Priority .

Trådar schemaläggs för körning baserat på deras prioritet. Även om trådar körs inom körningen tilldelas alla trådar processortidssektorer av operativsystemet. Informationen om schemaläggningsalgoritmen som används för att fastställa i vilken ordning trådar körs varierar med varje operativsystem. Under vissa operativsystem schemaläggs alltid tråden med högsta prioritet (av de trådar som kan köras) att köras först. Om flera trådar med samma prioritet är tillgängliga växlar schemaläggaren igenom trådarna med den prioriteten, vilket ger varje tråd en fast tidssektor som ska köras. Så länge en tråd med högre prioritet är tillgänglig för körning kan trådar med lägre prioritet inte köras. När det inte finns fler körningsbara trådar med en viss prioritet flyttas schemaläggaren till nästa lägre prioritet och schemalägger trådarna med den prioriteten för körning. Om en tråd med högre prioritet kan köras är tråden med lägre prioritet förinstallerad och tråden med högre prioritet tillåts köras igen. Dessutom kan operativsystemet också justera trådprioriteringar dynamiskt när ett programs användargränssnitt flyttas mellan förgrund och bakgrund. Andra operativsystem kan välja att använda en annan schemaläggningsalgoritm.

Exempel

Här är ett exempel på körningen av 9 trådar över alla 5 prioritetsnivåer från Thread.Priority uppräkningen där de sista 5 är på högsta prioritetsnivå. Dessutom har vi återanropsstöd från föregående artikel som i den här kontexten visar att ordningen för trådinitiering och prioritering kanske inte alltid återspeglas i efterföljande kod eller processkörningars startordning. Det innebär att vi här ser den parallella karaktären av kodkörning och demonstration av tilldelade processortidssektorer av operativsystemet för varje tråd. Detta belyser påverkan och kontroll av miljön där trådar körs. Med detta sagt ser vi verkligen att de högsta prioritetstrådarna verkligen får prioritet i körningen.

Följande kod ger godtyckliga resultat för varje körning. Vanliga sekvensmönster för prioriteringar som körs kan dock observeras efter att koden har körts flera gånger och analyserat utdata.

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

Se även