Материал: 6262

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

 

106

сеанса

групп процессов, принадлежавших сеансу.

Лидер сеанса

Процесс, создавший данный сеанс.

Управляющий

Терминал, ассоциированный с сеансом. У сеанса может быть не

терминал

более одного управляющего терминала, а тот, в свою очередь,

 

ассоциируется ровно с одним сеансом. Некоторые последова-

 

тельности символов, вводимые с управляющего терминала,

 

вызывают посылку сигналов всем процессам группы, ассоции-

 

рованной с данным управляющим терминалом.

Управляющий

Лидер сеанса, установивший соединение с управляющим

процесс

терми-налом. Если в дальнейшем терминал перестанет быть

 

управляю-щим для сеанса, лидер сеанса утратит статус

 

управляющего процесса.

Приоритетные

Имеют некоторые привилегии при доступе к управляющему

(переднего плана)

терминалу. В сеансе, установившем соединение с неким управ-

процессы

ляющим терминалом, может быть не более одной группы про-

 

цессов, приоритетной по отношению к данному управляющему

 

терминалу.

Фоновые

Неприоритетные к данному управляющему терминалу процес-

процессы

сы.

Реальный

Идентификатор пользователя, создавшего процесс.

идентификатор

 

пользователя

 

процесса

 

Реальный

Идентификатор группы пользователя, создавшего процесс.

идентификатор

 

группы процессов

 

Напомню, что для получения информации о процессах служит утилита ps, общий формат вызова которой имеет вид:

ps [-aA] [-defl] [-G список_групп]

[-o формат] ... [-p список_процессов]

[-t список_терминалов] [-U список_пользователей]

[-g список_групп]

[-n список_имен]

[-u список_пользователей]

Основной набор системных вызовов, обеспечивающих работу с указанными атрибутами процесса, рассмотрим в следующем подразделе данного пособия.

107

3.4 Системные вызовы ОС по управлению процессами

Управление процессами имеет достаточно развитый набор системных средств для управления ими. Мы рассмотрим только наиболее важные из них, которые к тому же соответствуют стандартам POSIX. В таблице 3.2 приведен перечень таких системных вызовов, которые разделены на три группы управления:

атрибутами процессов;

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

потоки и сигналы процессов.

Таблица 3.2 — Перечень системных вызовов ОС по управлению процессами

Функции управления атрибутами процессов

getpid Возвращает идентификатор ID текущего процесса.

getppid Возвращает идентификатор ID родительского процесса.

getpgrp Возвращает идентификатор ID группы процессов, к которой принадлежит текущий процесс.

getsid

Возвращает идентификатор (ID) сессии, для процесса заданного его

 

идентификатором ID.

setpgid

Присваивает идентификатор группы процессов тому процессу, кото-

 

рый задан своим номером ID.

setsid

Создает новый сеанс для текущего процесса, в котором этот процесс

 

становится ведущим группы.

 

Функции порождения и завершения процессов

fork

Создание нового процесса.

wait

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

waitpid

Ожидание завершения дочернего процесса, по заданному ID.

exec*

Набор системных вызовов для смены «тела» текущего процесса.

exit

Нормальное завершение процесса с заданным статусом.

atexit

Регистрация функции, которая будет вызвана при нормальном завер-

 

шении процесса (при вызове функции exit(...)).

Функции потоков и сигналов процессов

pthread_* Набор системных вызовов для организации и управления потоками.

signal

Установка нового обработчика сигнала текущего процесса.

kill

Посылка сигнала процессу по его идентификатору ID.

raise

Посылает сигнал текущему процессу.

pause

Остановка процесса до получения сигнала.

sleep

Остановка текущего процесса на заданное число секунд, либо до по-

 

лучения сигнала, который процесс не может игнорировать.

108

В данном подразделе будут рассмотрены системные вызовы, относящиеся к первой группе: управление атрибутами процессов.

Как было изучено ранее, каждый процесс ОС имеет свой уникальный целочисленный идентификатор ID (PID).

Такие же идентификаторы имеются и у групп процессов — GID.

Чтобы из программы, написанной на языке С, определить нужные идентификаторы атрибутов процессов, предусмотрены три системные функции getpid(...), getppid(...), getpgrp(...), синтаксис которых имеет вид:

#include <sys/types>

#include <unistd.h>

pid_t getpid (void); pid_t getppid (void); pid_t getpgrp (void); pid_t getsid (pid_t pid);

где pid — идентификатор процесса, для которого определяется идентификатор сессии; если значение pid = 0, то подразумевается pid текущего процесса.

Семантика этих функций следующая:

getpid(...) - возвращает PID текущего процесса;

getppid(...) - возвращает PID родительского процесса;

getpgrp(...) - возвращает GID текущего процесса;

getsid(...) - возвращает идентификатор сессии (SID) для процесса, заданного идентификатором PID.

По стандарту POSIX, первые три функции всегда завершаются успешно, поэтому ошибочных кодов возврата не предусмотренно.

Функция getsid(...), в случае ошибки, возвращает значение -1, а значение переменной errno будет содержать:

EPERM - процесс с номером pid существует, но он не находится в той же сессии, что и текущий процесс, в результате - это считается ошибкой;

ESRCH - не найден процесс с указанным номером pid.

Последние два системных вызова предназначены для установки идентификаторов групп. Общий синтаксис, соответствующих им функций, следующий:

#include <unistd.h>

int setpgid (pid_t pid, pid_t pgid); pid_t setsid (void);

где pid — идентификатор процесса, которому устанавливается идентификатор группы; если значение pid = 0, то подразумевается pid текущего процесса;

pgid — идентификатор устанавливаемой группы; если значение pgid = 0, то подразумевается pid текущего процесса.

109

Системный вызов setpgid(...) предназначен для установки идентификатора группы процессов, например, в целях управления заданиями. Его выполнение влечет либо присоединение к существующей группе процессов, либо создание новой группы в рамках сеанса, в которую входит вызывающий процесс.

При удачном выполнении setpgid(...) возвращает значение равное нулю. При ошибке возвращается -1, а переменной errno присваивается номер ошибки:

EINVAL - pgid меньше нуля;

EPERM - нарушение различных разрешений;

ESRCH - pid не является текущим процессом или подпроцессом текущего процесса.

Замечание

Процесс может установить идентификатор группы только для себя или порожденного процесса. Нельзя изменить идентификатор группы процессов лидера сеанса.

Системный вызов setsid(...) служит для создания нового сеанса и установки идентификатора группы текущему процессу.

Врезультате, вызывающий процесс становится:

ведущим процессом в группе;

ведущим процессом нового сеанса;

и не имеет контролирующего терминала.

Функция возвращает идентификатор сеанса вызывающего процесса. При ошибке возвращается -1, а переменной errno присваивается номер ошибки EPERM.

Замечание

Идентификаторы группы процессов и сеанса равными идентификатору вызывающего (текущего) процесса. Вызывающий процесс будет единственным в этой группе и сеансе.

Для демострации функциональных возможностей изученных системных вызовов, рассмотрим два примера.

Пример 1:

выводит на терминал идентификаторы, связанные с текущим процессом;

для текущего процесса проверяется и выводится на терминал сообщение о его лидерстве в группе;

если текущий процесс не является лидером, то он делается лидером новой сессии.

Программа, реализующая данный пример, представлена на листинге 3.1.

Листинг 3.1 — Реализация программы Примера 1

#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h>

110

// Функция вывода сообщений

 

 

 

int test_ids(void) {

 

 

 

pid_t pid, gid, sid;

 

 

 

int

ret = 0;

 

 

 

printf("Идентификатор текущего процесса:

%8i\n", pid = getpid());

printf("Идентификатор родительского процесса:

%8i\n",

getppid());

printf("Идентификатор группы текущего процесса:%8i\n", gid = getpgrp());

printf("Идентификатор сессии текущего процесса:%8i\n", sid = getsid(pid));

if (pid == gid) {

 

 

 

 

ret = -1;

 

 

 

}else

puts("Текущий процесс является

лидером группы...");

 

puts("Текущий процесс не является лидером группы...");

 

 

 

if (pid == sid) {

 

 

 

 

ret = -1;

 

 

 

}else

puts("Текущий процесс является

лидером сессии...");

 

 

 

 

 

puts("Текущий процесс не является лидером сессии..."); return ret;

}

// Главная функция int main(void) {

pid_t sid;

puts("Проект lab9.1 ..."); if (test_ids() == 0){

printf("Устанавливаю новый сеанс для текущего процесса:%8i\n", sid = setsid()); if (sid < 0) {

perror("setsid(): Не могу установить новую сессию...");

}

test_ids();

}

puts("Завершение проекта lab9.1 ..."); return EXIT_SUCCESS;

}

На рисунке 3.1 представлен вывод этой программы. Хорошо видно, что текущий процесс является лидером группы, но не является лидером сессии.

Рисунок 3.1 — Получение атрибутов текущего процесса

Источник: https://studfile.net/preview/16438530/