
- •Отчет по лабораторной работе №2 По дисциплине «Операционные системы»
- •Порядок выполнения работы
- •Контрольные вопросы
- •Определение потока. Для чего используются потоки?
- •Для чего используется функция потока?
- •Какие параметры можно передавать в функцию потока?
- •Как запускаются потоки? Как запустить поток в приостановленном
- •Как остановить поток?
- •Как возобновить выполнение потока?
- •Как поток может отказаться от своего кванта времени?
- •В чем состоит проблема синхронизации потоков?
- •Что такое критические секции и для чего они используются?
- •Какие правила необходимо соблюдать при использовании критических секций?
Определение потока. Для чего используются потоки?
В многопоточной среде программы могут быть разделены на части, называемые потоками выполнения (threads), которые выполняются одновременно. В терминах программы «поток» — это просто функция, которая может также вызывать другие функции программы. Программа начинает выполняться со своего главного (первичного) потока, который в традиционных программах на языке C является функцией main, а в Windows-программах — WinMain. Будучи выполняемой, функция может создавать новые потоки обработки, выполняя системный вызов с указанием функции инициализации потока (initial threading function). Операционная система в вытесняющем режиме переключает управление между потоками подобно тому, как она это делает с процессами.
Процесс фактически состоит из двух компонентов объекта ядра "процесс" и адресного пространства так вот, любой поток также состоит из двух компонентов.
объекта ядра, через который операционная система управляет потоком, там же хранится статистическая информация о потоке;
стека потока, который содержит параметры всех функций и локальные переменные, необходимые потоку для выполнения кода.
Для чего используется функция потока?
Будучи выполняемой, функция может создавать новые потоки обработки, выполняя системный вызов с указанием функции инициализации потока (initial threading function).
Каждый поток начинает выполнение с некой входной функции. В первичном потоке таковой является main, wmain, WinMain или wWinMain. При создании вторичного потока, в нем тоже должна быть входная функция, которая выглядит примерно так:
DWORD WINAPI ThreadFunc(PVOID pvParam) { DWORD dwResult = 0;
return(dwResult); }
Функция потока может выполнять любые задачи. Рано или поздно она закончит свою работу и вернет управление. В этот момент поток остановится, память, отведенная под его стек, будет освобождена, а счетчик пользователей его объекта ядра «поток» уменьшится на 1. Когда счетчик обнулится, этот объект ядра будет разрушен. Но, как и объект ядра «процесс», он может жить гораздо дольше, чем сопоставленный с ним поток.
А теперь поговорим о самых важных вещах, касающихся функций потоков:
В отличие от входной функции первичного потока, у которой должно быть одно из четырех имен: main, wmain, WinMain или wWinMain, — функцию потока можно назвать как угодно. Однако, если в программе несколько функций потоков, необходимо присвоить им разные имена, иначе компилятор или компоновщик решит, что создается несколько реализаций единственной функции.
Поскольку входным функциям первичного потока передаются строковые параметры, они существуют в ANSI- и Unicode-версиях: main - wmain и WinMain - wWinMain. Но функциям потоков передается единственный параметр, смысл которого определяется разработчиком, а не операционной системой. Поэтому здесь нет проблем с ANSI/Unicode.
Функция потока должна возвращать значение, которое будет использоваться как код завершения потока. Здесь полная аналогия с библиотекой С/С++: код завершения первичного потока становится кодом завершения процесса.
Функции потоков (да и остальные функции) должны по мере возможности обходиться своими параметрами и локальными переменными. Так как, кстати, ческой или глобальной переменной могут одновременно обратиться несколько потоков, есть риск повредить ее содержимое. Однако параметры и локальные переменные создаются в стеке потока, поэтому они в гораздо меньшей степени подвержены влиянию другого потока.