КаталогИндекс раздела
ОглавлениеВперед


      

Лабораторная работа N1

Цель работы: овладение системными программными средствами порождения и завершения процессов.

Процессы - общие сведения

Процесс в Unix/Linux представляет собой единицу работы вычислительной системы, которой операционная система выделяет ресурсы. С удовлетворительной степенью приближения можно определить процесс как выполняющуюся программу. Кардый процесс в системе имеет свой уникальный идентификатор процесса (PID), представляемый целым числом.

Каждому процессу в операционной системе соответствует запись в таблице процессов и адресное пространство процесса. Запись в таблице процессов (и ее расширение в адресном пространстве процесса) содержит управляющую информацию о ресурсах, выделенных процессу, и о состоянии процесса. Адресное пространство содержит коды и данные процесса.

Процесс может порождать другой процесс. Порождение нового процесса в Unix/Linux реализовано копированием записи таблицы процессов, таким образом, процесс-потомок в момент своего порождения представляет собой точную копию процесса-предка. Процесс-предок и процесс-потомок далее выполняются параллельно, но процесс-предок может и ожидать завершения процесса-потомка.

Процессы в Unix/Linux выполняются в режиме разделения времени, это означает, что время центрального процессора равномерно (с учетом приоритетов) распределяется между всеми готовыми к выполнению процессами. Даже если процесс не переходит в состояние ожидания (например, ожидания выполнения операции ввода-вывода) по своей инициативе, по истечении выделенного процессу кванта времени выполнение процесса будет прервано операционной системой, и процессор будет отдан более приоритетному процессу. Unix/Linux применяет динамическое перевычисление приоритетов, приоритет выполняющегося процесса понижается, а приоритеты ожидающих процессов повышаются.

Порождение процессов

Новый процесс порождается системным вызовом fork, который создает дочерний процесс - копию родительского. В дочернем процессе выполняется та же программа, что и в родительском, и когда дочерний процесс начинает выполняться, он выполняется с точки возврата из системного вызова fork. Системный вызов fork возвращает родительскому процессу PID дочернего процесса, а дочернему процессу - 0. По коду возврата вызова fork дочерний процесс может "осознать" себя как дочерний. Свой PID процесс может получить при помощи системного вызова getpid, а PID родительского процесса - при помощи системного вызова getppid. Если требуется, чтобы в дочернем процессе выполнялась программа, отличная от программы родительского процесса, процесс может сменить выполняемую в нем программу при помощи одного из системных вызовов семейства exec. Все вызовы этого семейства загружают для выполнения в процессе программу из заданного в вызове файла и отличаются друг от друга способом передачи параметров этой программе. Таким образом, наиболее распространенный контекст применения системного вызова fork выглядит примерно так:

    /* порождение дочернего процесса и запоминание его PID */
    if (!(ch_pid=fork()) 
        /* загрузка другой программы в дочернем процессе */
        exec(программа);
    else
        продолжение родительского процесса

Приоритет процесса

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

Процесс может изменить свой приоритет при помощи системного вызова nice, а приоритет дургого процесса может быть изменен системным вызовом setpriority.. Системный вызов getpriority позволяет узнать приоритет процесса.

Завершение процесса

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

Принудительное завершение процесса извне может быть выполнено при помощи системного вызова kill, посылающего процессу сигнал. Подробное рассмотрение сигналов мы проведем в следующей лабораторной работе, пока же только отметим, что гарантированно "убить" процесс, имеющий PID = p, можно системным вызовом:

    kill(p,SIGKILL)

Ожидание завершения процесса

Процесс-предок может ожидать завершения процесса-потомка (или процессов-потомков) при помощи системных вызовов wait или waitpid. Если процесс-потомок еще не завершился, процесс-предок переводится таким системным вызовом в состояние ожидания до завершения процесса-потомка (впрочем, процесс может и не ожидать завершения потомка, а только проверить, завершился ли он). Эти системные вызовы позволяют также процессу предку узнать код завершения потомка.

Постановка задачи

Для заданной в Вашем варианте индивидуального задания предметной области разработайте программную модель ситуации, включающей в себя следующее:

Отчет по лабораторной работе

Отчет по лабораторной работе должен содержать:

Пример выполнения работы N1 приведен здесь.


ОглавлениеВперед
КаталогИндекс раздела