Главная страница Случайная лекция Мы поможем в написании ваших работ! Порталы: БиологияВойнаГеографияИнформатикаИскусствоИсторияКультураЛингвистикаМатематикаМедицинаОхрана трудаПолитикаПравоПсихологияРелигияТехникаФизикаФилософияЭкономика Мы поможем в написании ваших работ! |
Завершение потоковЛюбой поток может быть завершен одним из следующих 4 способов: 1) естественный. Функция потока выполняется до конца, и возвращает управление в ОС; 2) поток самоуничтожается путем вызова в нем ExitThread (); 3) любой другой поток данного или иного процесса вызывает функцию уничтожения потока TerminateThread (); 4) завершение процесса, содержащего данный поток. Наиболее корректным для системы является первый способ. В этом случае, выполняются следующие системные действия: 1) все объекты, созданные в программе потока, уничтожаются соответствующими деструкторами; 2) система корректно освобождает память, которую занимал стек потока; 3) система устанавливает код завершения данного потока, который возвращается из прикладной функции потока (из программы потока); 4) счетчик числа пользователей объекта ядра «поток» уменьшается на единицу. Во втором способе, вызывается в потоке и принудительно исполняется функция ExitThread (). При этом, освобождаются все системные ресурсы, выделенные потоку, в частности, стек. Но все объектные ресурсы, созданные в программе потока, не уничтожаются. В функцию ExitThread передается значение, которое рассматривается системой, как код завершения всего потока. В третьем способе, в любом другом потоке процесса выполняется функция TerminateThread. Она имеет два параметра. В первом параметре задается дескриптор завершаемого потока, а второй параметр интерпретируется как код завершения для уничтожаемого потока. Особенность исполнения этой функции состоит в том, что её вызов оказывается внезапным для потока, и в следствие этого, в потоке не могут быть выполнены все действия для корректного освобождения системных и объектных ресурсов. В первых двух способах завершения стек уничтожается. В третьем способе стек сохраняется до момента завершения процесса, которому принадлежит уничтожаемый поток. Это сделано для того, чтобы другие потоки могли использовать указатели, ссылающиеся на данные в стеке завершаемого потока. В любом случае, некорректное освобождение ресурсов может привести к ошибке. Четвертый способ. Поток завершается в результате окончания всего процесса. В этом случае, выполняется функция ExitProcess () или TerminateProcess (). В результате, выполняется освобождение выделенных для процесса ресурсов, в том числе и освобождение стеков всех потоков. Однако, при этом деструкторы созданных объектов не вызываются, и промежуточные данные не переписываются на диск для сохранения, и следовательно, завершение потока выполняется некорректно. В любом из четырех рассмотренных случаев, в системе дополнительно реализуются дополнительные операции: 1) освобождаются все дескрипторы интерфейсных объектов, которые принадлежали потоку, то есть окна, меню, значки, шрифты, курсоры, и т.д.; 2) код завершения потока меняется с исходного значения 0x103 на действительное, которое вырабатывается в системе; 3) объект ядра «поток» из состояния «занято» переводится в состояние «свободно», но при этом, объект полностью не освобождается до тех пор, пока на него не будут закрыты все внешние ссылки; 4) счетчик числа пользователей объекта ядра «поток» уменьшается на единицу; 5) если данный поток был самым последним активным потоком процесса, то завершается и сам процесс. Планирование потоков. Приостановка и возобновление процессов и потоков. В ОС Windows используется вариант мультипрограммного режима работы, называемый вытесняющей многозадачностью. Для её реализации, в системе используется алгоритм, позволяющий распределять процессорное время между потоками. В версиях системы Windows 2000 и далее примерно каждые 18мс в системе просматриваются все существующие объекты ядра типа «поток», и отмечаются те из них, которые готовы получить процессорное время. Далее, в соответствии с принятым алгоритмом, выбирается один из них, и из его контекста загружаются регистры процессора. Данная операция называется переключением контекста потока. Затем, в течение интервала квантования, программа потока выполняется в адресном пространстве своего процесса. По окончании этого интервала, система сохраняет состояния регистров процессора в структуре CONTEXT данного потока, и приостанавливает его выполнение. Затем снова просматриваются все объекты ядра типа поток, выбирается один из них на основе алгоритма дисциплины распределения процессорного времени, в процессор загружается его контекст, и начинается выполнение программы этого потока, либо продолжение выполнения программы ранее прерванного потока. Подобный цикл операций, включающий: 1) выбор потока для запуска; 2) загрузку его контекста; 3) исполнение программы потока в процессоре в течение интервала квантования; 4) сохранение контекста; начинается с момента запуска системы вплоть до её выключения. Из приведенного общего описания алгоритма распределения процессорного времени между потоками следует, что в режиме вытесняющей многозадачности в системе в каждый момент времени присутствуют потоки следующих типов: 1) выполняющиеся в процессоре; 2) планируемые к выполнению; 3) приостановленные системой; 4) ожидающие возникновения каких-либо событий. В объекте ядра «поток» имеется системная переменная SUSPENDCOUNT, которая называется счетчиком числа простоев данного потока. Если его значение равно нулю, то соответствующий поток приостанавливается, и не получает процессорного времени. При вызове функций CreateProcess () и CreateThread () эта переменная инициализируется единицей, которая запрещает системе немедленно выделять новому потоку процессорное время, поскольку требуется его инициализация. После выполнения инициализации проверяется состояние одного из флагов функции создания потока CreateThread, а именно P5. Если он равен единице, то поток оставляется в приостановленном состоянии. Если этот флаг сброшен, то SUSPENDCOUNT обнуляется, и поток включается в число планируемых к выполнению в процессоре. Новый поток может быть изначально создан как приостановленный, если упомянутый флаг имеет исходное значение единицы. В этом случае, в системе имеется возможность изменить какие-либо свойства потока, например, его приоритет. После подобной настройки потока, ему может быть разрешено выполнение в процессоре. В этом случае, реализуется процедура возобновления потока. С этой целью в системе используется функция ResumeThread (), в которую в качестве параметра передается дескриптор потока, возвращаемый функцией создания потока. Если поток ожидает наступления какого-либо внешнего события, например, ввода данных с клавиатуры, то он будет находиться в этом состоянии, называемом состоянием блокирования, до момента возникновения этого события. Затем поток снова включается в число планируемых к выполнению. Поток может быть приостановлен не только в момент его создания, но и в ходе свого выполнения. Для этого используется системная функция SuspendThread (). Параметром функции является описатель приостанавливаемого потока. Эта функция может быть вызвана из любого другого потока, если известен его описатель. Поток может быть приостановлен не более чем устанавливаемое в системе количество раз. С помощью функции Sleep () поток может запросить у системы возможность не выделять ему процессорное время на определенный период времени, то есть запросить возможность приостановки самого себя. Параметр – период приостановки в миллисекундах. После её выполнения поток приостанавливается, и у него отбирается остаток выделенного ему кванта процессорного времени. По окончании периода приостановки, система переводит поток в число планируемых, после чего он продолжает свое выполнение. В системе имеется также функция SwitchToThread (), с помощью которой система может подключить процессору новый поток, если он имеется. При вызове этой функции, система проверяет, присутствует ли поток, которому хронически не хватает процессорного времени («голодание потока»). Если такого потока нет, то данная функция просто завершается. Если подобный поток обнаруживается, то ему выделяется дополнительный квант времени. При этом, с помощью данной функции может быть выделено время потоку с более низким приоритетом, чем потоки, которые до этого выполнялись в процессоре. В системах Windows, понятия, о которых здесь шла речь, а именно – приостановка и возобновление, неприменимы к процессам, поскольку процессы в распределении процессорного времени непосредственно не участвуют. Существует лишь одна возможность приостановить одновременно все потоки какого-либо процесса. Это можно сделать из другого процесса, который является отладочным.
Дата добавления: 2014-10-10; просмотров: 540; Нарушение авторских прав Мы поможем в написании ваших работ! |