Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Każdy wątek ma przypisany priorytet wątku. Wątki utworzone w środowisku uruchomieniowym języka wspólnego są początkowo przypisywane priorytetowi ThreadPriority.Normal. Wątki utworzone poza środowiskiem uruchomieniowym zachowują priorytet, jaki mieli przed wejściem do środowiska zarządzanego. Możesz uzyskać lub ustawić priorytet dowolnego wątku z właściwością Thread.Priority .
Wątki są przydzielane do wykonania na podstawie ich priorytetu. Nawet jeśli wątki działają w środowisku uruchomieniowym, system operacyjny przydziela im wycinki czasu procesora. Szczegóły algorytmu planowania używanego do określania kolejności wykonywania wątków różnią się w zależności od systemu operacyjnego. W niektórych systemach operacyjnych wątek o najwyższym priorytcie (z tych wątków, które można wykonać) jest zawsze zaplanowany do pierwszego uruchomienia. Jeśli wszystkie wątki z tym samym priorytetem są dostępne, harmonogram będzie przechodził przez wątki o tym priorytcie, dając każdemu wątkowi stały wycinek czasu, w którym ma zostać wykonany. Jeśli wątki o wyższym priorytcie są dostępne do uruchomienia, wątki o niższym priorytcie nie są wykonywane. Jeśli nie ma więcej wątków możliwych do uruchomienia w danym priorytecie, planista przechodzi do następnego niższego priorytetu i planuje wykonanie wątków o tym priorytecie. Jeśli wątek o wyższym priorytecie staje się gotowy do działania, wątek o niższym priorytecie zostaje wywłaszczony, a wątek o wyższym priorytecie zyskuje możliwość ponownego wykonania. W dodatku system operacyjny może również dynamicznie dostosowywać priorytety wątków, gdy interfejs użytkownika aplikacji jest przenoszony między pierwszym planem a tłem. Inne systemy operacyjne mogą zdecydować się na użycie innego algorytmu planowania.
Przykład
Oto przykład wykonywania 9 wątków na wszystkich 5 poziomach priorytetu z Thread.Priority wyliczenia, w którym ostatnie 5 jest na najwyższym poziomie priorytetu. Ponadto mamy obsługę wywołania zwrotnego z poprzedniego artykułu, co w tym kontekście pokazuje, że kolejność inicjalizacji wątku i priorytetyzacji może nie zawsze być odzwierciedlana w kolejnym kodzie ani w kolejności rozpoczęcia wykonywania procesów. Oznacza to, że widzimy tutaj równoległy charakter wykonywania kodu oraz demonstrację przypisanych przez system operacyjny wycinków czasu procesora dla każdego wątku. Podkreśla to wpływ i kontrolę środowiska, w którym działają wątki. W tym przypadku z pewnością widzimy, że wątki o najwyższym priorytcie są rzeczywiście traktowane priorytetowo w wykonaniu.
Poniższy kod spowoduje wygenerowanie dowolnych wyników dla każdego wykonania. Jednak typowe wzorce sekwencji priorytetów, które są uruchamiane, można zaobserwować po wielokrotnym uruchomieniu kodu i przeanalizowaniu danych wyjściowych.
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.
}