Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Každé vlákno má přiřazenou prioritu vlákna. Vlákna vytvořená v modulu CLR (Common Language Runtime) mají zpočátku přiřazenou prioritu ThreadPriority.Normal. Vlákna vytvořená mimo runtime si zachovají prioritu, kterou měla před vstupem do spravovaného prostředí. Můžete získat nebo nastavit prioritu libovolného vlákna s Thread.Priority vlastností.
Vlákna jsou naplánována k provedení na základě jejich priority. Přestože vlákna jsou spouštěna v rámci modulu runtime, operační systém přiřazuje všem vláknům časové úseky procesoru. Podrobnosti o algoritmu plánování použitém k určení pořadí, ve kterém se vlákna spouští, se liší podle jednotlivých operačních systémů. V některých operačních systémech je vlákno s nejvyšší prioritou (z vláken, která lze spustit), vždy naplánováno tak, aby se spustilo jako první. Pokud je k dispozici více vláken se stejnou prioritou, plánovač prochází vlákny s danou prioritou, čímž každému vláknu poskytne pevný časový řez, ve kterém se má provést. Dokud je vlákno s vyšší prioritou k dispozici ke spuštění, vlákna s nižší prioritou se nespustí. Pokud na dané prioritě nejsou žádná další spustitelná vlákna, plánovač se přesune na další nižší prioritu a naplánuje vlákna s touto prioritou k vykonání. Pokud se vlákno s vyšší prioritou stane připraveným k běhu, vlákno s nižší prioritou je přerušeno a vlákno s vyšší prioritou může opět běžet. Kromě toho může operační systém také dynamicky upravovat priority vláken, protože uživatelské rozhraní aplikace se přesouvá mezi popředím a pozadím. Jiné operační systémy se můžou rozhodnout použít jiný algoritmus plánování.
Příklad
Tady je příklad spuštění 9 vláken ve všech 5 úrovních priority z Thread.Priority výčtu, kde posledních 5 je na nejvyšší úrovni priority. Máme také mechanismus zpětného volání z předchozího článku, který v tomto kontextu ukazuje, že pořadí inicializace vlákna a prioritizace nemusí být vždy zohledněno v následném kódu ani v pořadí spouštění procesů. To znamená, že zde vidíme paralelní způsob provádění kódu a ukázku přiřazených časových úseků procesoru operačním systémem pro každé vlákno. Tím se zdůrazňuje vliv prostředí, které ovlivňuje a řídí běh vláken. Díky tomu jistě vidíme, že vlákna s nejvyšší prioritou skutečně dostávají prioritu při provádění.
Následující kód při každém spuštění vytvoří libovolné výsledky. Běžné vzory sekvencí spuštěných priorit se ale dají pozorovat po vícenásobném spuštění kódu a analýze výstupů.
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.
}