Подсистема управления процессами
Курсовой проект - Компьютеры, программирование
Другие курсовые по предмету Компьютеры, программирование
?оков того же процесса. Существует 5 градаций приоритета потока:enum ThreadPriority { Lowest, BelowNormal, Normal, AboveNormal, Highest }
Значение приоритета становится существенным, когда одновременно исполняются несколько потоков.
Установка приоритета потока на максимум еще не означает работу в реальном времени (real-time), так как существуют еще приоритет процесса приложения. Чтобы работать в реальном времени, нужно использовать класс Process из пространства имен System.Diagnostics для поднятия приоритета процесса .
От ProcessPriorityClass.High один шаг до наивысшего приоритета процесса Realtime. Устанавливая приоритет процесса в Realtime, вы говорите операционной системе, что хотите, чтобы ваш процесс никогда не вытеснялся. Если ваша программа случайно попадет в бесконечный цикл, операционная система может быть полностью заблокирована. Спасти вас в этом случае сможет только кнопка выключения питания. По этой причине ProcessPriorityClass.High считается максимальным приоритетом процесса, пригодным к употреблению.
Если real-time приложение имеет пользовательский интерфейс, может быть не желательно поднимать приоритет его процесса, так как обновление экрана будет съедать чересчур много времени CPU тормозя весь компьютер, особенно если UI достаточно сложный.
Способы синхронизации потоков
Оператор lock (aka Monitor.Enter/Monitor.Exit) один из примеров конструкций синхронизации потоков. Lock является самым подходящим средством для организации монопольного доступа к ресурсу или секции кода, но есть задачи синхронизации (типа подачи сигнала начала работы ожидающему потоку), для которых lock будет не самым адекватным и удобным средством.
В Win32 API имеется богатый набор конструкций синхронизации, и они доступны в .NET Framework в виде классов EventWaitHandle, Mutex и Semaphore. Некоторые из них практичнее других: Mutex, например, по большей части дублирует возможности lock, в то время как EventWaitHandle предоставляет уникальные возможности сигнализации.
Все три класса основаны на абстрактном классе WaitHandle, но весьма отличаются по поведению. Одна из общих особенностей это способность именования, делающая возможной работу с потоками не только одного, но и разных процессов.
EventWaitHandle имеет два производных класса AutoResetEvent и ManualResetEvent (не имеющие никакого отношения к событиям и делегатам C#). Обоим классам доступны все функциональные возможности базового класса, единственное отличие состоит в вызове конструктора базового класса с разными параметрами.
В части производительности, все WaitHandle обычно исполняются в районе нескольких микросекунд. Это редко имеет значение с учетом контекста, в котором они применяются.
AutoResetEvent наиболее часто используемый WaitHandle-класс и основная конструкция синхронизации, наряду с lock.
AutoResetEvent очень похож на турникет один билет позволяет пройти одному человеку. Приставка "auto" в названии относится к тому факту, что открытый турникет автоматически закрывается или "сбрасывается" после того, как позволяет кому-нибудь пройти. Поток блокируется у турникета вызовом WaitOne (ждать (wait) у данного (one) турникета, пока он не откроется), а билет вставляется вызовом метода Set. Если несколько потоков вызывают WaitOne, за турникетом образуется очередь. Билет может "вставить" любой поток другими словами, любой (неблокированный) поток, имеющий доступ к объекту AutoResetEvent, может вызвать Set, чтобы пропустить один блокированный поток.
Если Set вызывается, когда нет ожидающих потоков, хэндл будет находиться в открытом состоянии, пока какой-нибудь поток не вызовет WaitOne. Эта особенность помогает избежать гонок между потоком, подходящим к турникету, и потоком, вставляющим билет ("опа, билет вставлен на микросекунду раньше, очень жаль, но вам придется подождать еще сколько-нибудь!"). Однако многократный вызов Set для свободного турникета не разрешает пропустить за раз целую толпу сможет пройти только один человек, все остальные билеты будут потрачены впустую.
WaitOne принимает необязательный параметр timeout метод возвращает false, если ожидание заканчивается по таймауту, а не по получению сигнала. WaitOne также можно обучить выходить из текущего контекста синхронизации для продолжения ожидания (если используется режим с автоматической блокировкой) во избежание чрезмерного блокирования.
Метод Reset обеспечивает закрытие открытого турникета, безо всяких ожиданий и блокировок.
AutoResetEvent может быть создан двумя путями. Во-первых, с помощью своего конструктора:EventWaitHandle wh = new AutoResetEvent(false);
Если аргумент конструктора true, метод Set будет вызван автоматически сразу после создания объекта.
Другой метод состоит в создании объекта базового класса, EventWaitHandle:EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.Auto);
Конструктор EventWaitHandle также может использоваться для создания объекта ManualResetEvent (если задать в качестве параметра EventResetMode.Manual).
Метод Close нужно вызывать сразу же, как только WaitHandle станет не нужен для освобождения ресурсов операционной системы. Однако если WaitHandle используется на протяжении всей жизни приложения (как в большинстве примеров этого раздела), этот шаг можно опустить, так как он будет выполнен автоматически при разрушении домена приложения.
ManualResetEvent это разновидность AutoResetEvent. Отличие состоит в том, что он не сбрасывается автоматически, после того как поток проходит через WaitOne, и действует как шлагбаум Set открывает его, позволяя пройти любому количеству потоков, вызвавших WaitOne. Reset закрывает шлагбаум, потенциально накапливая очередь ожидающих следующего открытия.
Эту функциональность можно эмулировать при помощи