
- •Раздел 3. Параллельное выполнение программ
- •3.1. Концепция процесса
- •3.2. Средства описания параллелизма
- •3.2.1. Графические средства
- •3.2.3. Описание процессов средствами uml
- •3.2.4. Языковые средства описания параллелизма
- •3.3. Организация ядра ос
- •3.3.1. Ядро как средство организации виртуальной машины
- •3.3.2. Состояния процесса и структура ядра
- •3.3.3. Дескрипторы процессов
- •3.3.4. Очереди процессов в ядре
- •3.4. Общая характеристика примитивов ядра
- •3.5. Примитивы создания и уничтожения процессов
- •3.6. Примитивы синхронизации процессов
- •3.6.1. Простейшие примитивы, не учтенные в классификации
- •3.6.2. Примитивы временной синхронизации
- •3.6.3. Примитивы событийной синхронизации процессов
- •3.7. Общий семафор как средство событийной синхронизации
- •3.8. Средства синхронизации в существующих операционных системах
- •3.9. Монитор как средство реализации взаимного исключения
- •3.10. Примитивы ядра для обмена сообщениями
- •3.10.1. Буфер как средство коммуникации между процессами
- •3.10.2. Почтовый ящик с очередью сообщений
- •3.10.3. Средства коммуникаций в существующих ос
- •3.11. Проблема тупиков при взаимодействии процессов
- •3.12. Планирование загрузки процессора в ядре
- •3.12.1. Классификация алгоритмов планирования
- •3.12.2. Тесты планируемости задач и классификация задач
- •3.12.3. Динамическое планирование
- •3.12.3.1. Планирование независимых задач
- •1. Алгоритм монотонной скорости.
- •2. Алгоритм “задача с минимальным предельным сроком завершения - первая”
- •3. Алгоритм минимальной неопределенности
- •3.12.3.2. Планирование зависимых задач
- •3.12.4. Статическое планирование
3.5. Примитивы создания и уничтожения процессов
Создание процесса
Конкретная реализация примитива зависит от реализации ядра.
Паскале-подобная запись примитива создания процесса может выглядеть следующим образом:
Вопрос (
Procedure Создать_Процесс(Var P : Process; Данные);
{Данные - приоритет, точка входа, размер стека и др.}
Begin
ПРОЛОГ;
КОНТРОЛЬ;
<
Создать дескриптор;
Заполнить поля дескриптора;
Ввести процесс в очередь готовых процессов;
>
ПЕРЕНАЗНАЧИТЬ_ПРОЦЕССОР;
End {Создать_Процесс};
)Вопрос
Активный процесс создает новый процесс вызовом:
Создать_Процесс(P, Д);
Могут быть синтаксические различия в вызовах примитивов в различных средах.
Уничтожение процесса
Для уничтожения процесса логично выполнить действия, обратные созданию процесса:
Procedure Уничтожить_Процесс(P : Process);
Begin
ПРОЛОГ;
КОНТРОЛЬ;
<
Вывести процесс из очереди, в которой он находится;
Разрушить дескриптор процесса;
>
ПЕРЕНАЗНАЧИТЬ_ПРОЦЕССОР;
End {Уничтожить_Процесс};
Такой вид примитива Уничтожить_Процесс допустим, если некоторый выполняющийся процесс Р, хочет уничтожить некоторый процесс Q.
Хотя и здесь есть проблемы, а именно:
Если процесс будет уничтожен в критическом участке, то это может вызвать блокировку, т.к. он никогда не сможет освободить занятый ресурс. Поэтому уничтожение процесса должно сопровождаться освобождением ресурсов, выделенных ему. Может быть по протоколу ядра должны быть уничтожены и процессы-наследники. Для этого в дескриптор процесса включаются указатели на списки выделенных ресурсов и процессов-наследников. Т.е. реальный примитив Уничтожить_Процесс может оказаться гораздо сложнее.
Такой вариант примитива не может быть использован для уничтожения процессом самого себя. Предположим, что выполняющийся процесс вызывает примитив Уничтожить_Процесс(Self). В соответствие с кодом примитива сначала разрушается дескриптор, а затем вызывается примитив ПЕРЕНАЗНАЧИТЬ_ПРОЦЕССОР. Т.к. примитиву ПЕРЕНАЗНАЧИТЬ_ПРОЦЕССОР передаются указатели на дескрипторы процессов: «от кого» и «кому» , а дескриптор «от кого» уже разрушен, то вызов примитива ПЕРЕНАЗНАЧИТЬ_ПРОЦЕССОР окажется некорректным. Т. е. разрушен дескриптор процесса, который еще выполняется.
Поэтому уничтожение процессов выполняется несколько иначе.
Вопрос (
Создается специальная очередь уничтожаемых процессов;
Примитив Уничтожить_Процесс в действительности не уничтожает процесс, а переводит его в эту очередь уничтожаемых процессов. Т. е. примитив Уничтожить_Процесс имеет следующий вид:
Procedure Уничтожить_Процесс(P : Process);
Begin
ПРОЛОГ;
КОНТРОЛЬ;
<
Вывести процесс из очереди, в которой он находится;
Ввести процесс в очередь уничтожаемых процессов;
>
ПЕРЕНАЗНАЧИТЬ_ПРОЦЕССОР;
End {Уничтожить_Процесс};
При каждом вызове процедуры Диспетчера осуществляется очистка очереди уничтожаемых процессов с фактическим их уничтожением.
)Вопрос
Таким образом, диспетчер модифицируется следующим образом:
Procedure Dispatcher; Interrupt;
Begin
ОЧИСТИТЬ_ОЧЕРЕДЬ_УНИЧТОЖАЕМЫХ_ПРОЦЕССОВ;
ПЕРЕНАЗНАЧИТЬ_ПРОЦЕССОР;
End;