Учебно-методический комплекс общее количество часов 58 ч. Лекции 28 ч


Download 2.46 Mb.
bet70/91
Sana19.10.2023
Hajmi2.46 Mb.
#1709453
TuriУчебно-методический комплекс
1   ...   66   67   68   69   70   71   72   73   ...   91
Bog'liq
Язык программирования C#

15.3. Приоритет потоков

Все потоки в CLR длятся на два типа: основные (приоритетные) и фоновые. Различие между ними заключается в том, что процесс не завершится, пока работает хотя бы один основной поток, а при завершении всех основных потоков фоновые потоки автоматически прерываются и процесс завершает работу. По умолчанию потоки создаются приоритетными.


Статус потока переключается с основного на фоновый посредством свойства IsBackground. Изменение статуса потока с основного на фоновый не изменяет его приоритет или статус в планировщике потоков. Примером фонового процесса является проверка правописания в Microsoft Word. Ясно, что при завершении работы главного потока этот фоновый поток становится ненужным.
Процессорное время и другие ресурсы делятся между конкурирующими между собой потоками приложения, исходя из их приоритетов. Существует 5 градаций приоритета потока. Для установки приоритета потока используется свойство Thread.Priority, которое имеет тип перечисления Threading.ThreadPriority.

enum ThreadPriority { Lowest, BelowNormal, Normal, AboveNormal, Highest }


Лист. 5.8

Значение приоритета становится существенным, когда одновременно исполняются несколько потоков. Приведем теперь пример многопоточного приложения с использованием приоритетов.


using System;


using System.Threading;

namespace Thread_Priority


{
class Counter
{
// определяют границы для прохода
static int StartNumber = 0, FinishNumber = 10000;
// определяет сигнал для завершения всех потоков
static bool IsFinishNumberReached = false;

// число, до которого дошел поток


public int CurrentNumber;

// метод для запуска потока


public void Count()
{
// выводим информацию о запущенном потоке
Console.WriteLine(Thread.CurrentThread.Name + " запустился.");
// поток считает от StartNumber до FinishNumber и этим эмулирует
// длительный прцесс
for (CurrentNumber = StartNumber; CurrentNumber <= FinishNumber;
CurrentNumber++)
{
// если один из потоков
if (IsFinishNumberReached)
break;
Console.WriteLine(CurrentNumber + " " + Thread.CurrentThread.Name);
}
// из-за особенностей цикла for поток, досчитавший FinishNumber,
// будет на единицу больше FinishNumber
If (CurrentNumber > FinishNumber)
CurrentNumber = FinishNumber;
// как только один из потоков досчитал до FinishNumber, он
// сигнализирует об этом всем остальным
IsFinishNumberReached = true;
// сообщаем о завершении потока
Console.WriteLine(Thread.CurrentThread.Name + " завершился.");
}
}

class Program


{
static void Main(string[] args)
{
// создаем три счетчика
Counter c1, c2, c3;
c1 = new Counter();
c2 = new Counter();
c3 = new Counter();
// на основе этих счетчиков создаем три потока с
// РАЗНЫМ приоритетом
Thread t1, t2, t3;
t1 = new Thread(new ThreadStart(c1.Count));
t1.Name = "Поток #1";
t1.Priority = ThreadPriority.Normal;
t2 = new Thread(new ThreadStart(c2.Count));
t2.Name = "Поток #2";
t2.Priority = ThreadPriority.AboveNormal;
t3 = new Thread(new ThreadStart(c3.Count));
t3.Name = "Поток #3";
t3.Priority = ThreadPriority.Highest;

// запускаем потоки


t1.Start();
t2.Start();
t3.Start();

// присоединяем потоки к основному, иначе основной поток может


// закончиться раньше их
t1.Join();
t2.Join();
t3.Join();

// выодим окончательное состояние потоков


Console.WriteLine(t1.Name + " досчитал до " + c1.CurrentNumber);
Console.WriteLine(t2.Name + " досчитал до " + c2.CurrentNumber);
Console.WriteLine(t3.Name + " досчитал до " + c3.CurrentNumber);
}
}
}
Лист. 5.9

Первым в листинге определяется класс Counter. Единственный метод Count() этого класса выводит на консоль целые числа, начиная от StartNumber, и, кончая FinishNumber. Такой отсчет делается для эмуляции некоторого длительного процесса.


for(CurrentNumber=StartNumber;CurrentNumber<=FinishNumber;CurrentNumber++)


{
// если один из потоков
if (IsFinishNumberReached)
break;
Console.WriteLine(CurrentNumber + " " + Thread.CurrentThread.Name);
}
Лист. 5.10

Текущее число, до которого досчитал метод Count(), хранится в переменной CurrentNumber. Если счетчик CurrentNumber достигает значения FinishNumber, то метод Count() присваивает статической переменной IsFinishNumberReached значение true. Так как переменная IsFinishNumberReached статическая, то её изменения видны для всех экземпляров класса Counter. Перед каждой итерацией счетчика проверяется значение IsFinishNumberReached, и если оно выставлено в true, то выполнение цикла счетчика прерывается.


В методе Main() создаются три объекта класса Counter, и для каждого объекта создается отдельный поток. Разным потокам присваиваются разные имена и разные приоритеты, так первый поток имеет наименьший приоритет, а последний наибольший.

Thread t1, t2, t3;


t1 = new Thread(new ThreadStart(c1.Count));
t1.Name = "Поток #1";
t1.Priority = ThreadPriority.Normal;
t2 = new Thread(new ThreadStart(c2.Count));
t2.Name = "Поток #2";
t2.Priority = ThreadPriority.AboveNormal;
t3 = new Thread(new ThreadStart(c3.Count));
t3.Name = "Поток #3";
t3.Priority = ThreadPriority.Highest;
Лист. 5.11

Далее все потоки запасаются и начинают работать.


t1.Start();


t2.Start();
t3.Start();
Лист. 5.12

Чтобы основной поток приложения не завершился раньше времени, он объединяется со всеми остальными потоками.


t1.Join();


t2.Join();
t3.Join();
Лист. 5.13

В конце выводим, до какого числа успели досчитать потоки.


Console.WriteLine(t1.Name + " досчитал до " + c1.CurrentNumber);


Console.WriteLine(t2.Name + " досчитал до " + c2.CurrentNumber);
Console.WriteLine(t3.Name + " досчитал до " + c3.CurrentNumber);
Лист. 5.14

Вывод программы очень разнится на разных машинах и даже на одной машине в зависимости от загрузки процессора. Поэтому читатель должен сам запустить эту программу у себя на машине и оценить результаты.





Download 2.46 Mb.

Do'stlaringiz bilan baham:
1   ...   66   67   68   69   70   71   72   73   ...   91




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling