Механизмы управления программами

Содержание

Слайд 2

Структура раздела Процессы Понятие процесса Управление процессами Процессы и потоки Параллельные

Структура раздела

Процессы
Понятие процесса
Управление процессами
Процессы и потоки
Параллельные процессы
Процессы в ОС UNIX
Атрибуты

процессов
Состояния процесса
Создание и уничтожение процессов
Организация взаимодействия процессов
Процессы в ОС Windows
Особенности процессов
Взаимодействие процессов
Слайд 3

Процессы

Процессы

Слайд 4

Понятие процесса Процесс – некоторая деятельность, связанная с исполнением программы на

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

Процесс – некоторая деятельность, связанная с исполнением программы на процессоре.
Процесс

– система действий, реализующая определенную функцию в вычислительной системе и оформленная так, что управляющая программа вычислительной системы может перераспределять ресурсы этой системы в целях обеспечения мультипрограммирования. [ГОСТ 19781-83]
Слайд 5

Виды процессов По принадлежности к центральному процессору Внутренние процессы – связаны

Виды процессов

По принадлежности к центральному процессору
Внутренние процессы – связаны с программами,

исполняемыми на центральном процессоре.
Внешние процессы – программы, выполняемые на дополнительных процессорах, операции ввода и вывода, выполняемые на периферийных устройствах.
По принадлежности к операционной системе.
Системные процессы – реализуют функции операционной системы.
Пользовательские процессы – связаны с выполнением прикладных программ.
Слайд 6

По динамическому признаку Последовательные процессы – процессы, которые не могут выполняться

По динамическому признаку
Последовательные процессы – процессы, которые не могут выполняться одновременно.
Параллельные

процессы – одновременно выполняющиеся процессы.
Комбинированные – если в процессах имеются точки, в которых существует один из параллельных процессов и не существует другой.
По связности
Изолированные процессы – полностью независимые процессы.
Информационно-независимые процессы – используют общие ресурсы, но не связаны по информации.
Взаимодействующие процессы – процессы имеют информационные связи.
Конкурирующие – процессы взаимосвязаны по информации и используют общие ресурсы.
Слайд 7

Состояния процесса Порождение Готовность Активное Ожидание Окончание

Состояния процесса

Порождение

Готовность

Активное

Ожидание

Окончание

Слайд 8

Атрибуты процессов Идентификатор процесса Таблицы адресов выделенных процессу областей памяти Таблицы

Атрибуты процессов

Идентификатор процесса
Таблицы адресов выделенных процессу областей памяти
Таблицы файлов
Приоритет процесса
Состояние процесса
Информация

о связанных с процессом событиях
Контекст процесса
Слайд 9

Управление процессами Основные функции ОС Создание и удаление процессов Планирование и

Управление процессами

Основные функции ОС
Создание и удаление процессов
Планирование и диспетчеризация
Синхронизация процессов и

обеспечение их средствами взаимодействия
Слайд 10

Планирование Планирование – управление очередями с целью минимизации задержек и максимизации

Планирование

Планирование – управление очередями с целью минимизации задержек и максимизации производительности

системы
Виды планирования
Долгосрочное планирование
Среднесрочное планирование
Краткосрочное планирование (диспетчеризация)
Слайд 11

Уровни планирования Создание Завершение Выполнение Готов Блокирован Блокирован приостановлен Готов приостановлен

Уровни планирования

Создание

Завершение

Выполнение

Готов

Блокирован

Блокирован приостановлен

Готов приостановлен

Краткосрочное планировани

Краткосрочное планирование

Среднесрочное планирование

Долгосрочное планирование

Слайд 12

Дисциплины диспетчеризации Бесприоритетные Приоритетные Линейные Нелинейные В порядке очереди Случайный выбор

Дисциплины диспетчеризации

Бесприоритетные

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

Линейные

Нелинейные

В порядке очереди

Случайный выбор

Циклический алгоритм

Многоприоритетный циклический

С относительным приоритетом

С абсолютным приоритетом

Адаптивное

обслуживание

Приоритет зависит от времени ожидания

Приоритет зависит от времени обслуживания

Фиксированные приоритеты

Динамические приоритеты

Слайд 13

В порядке очереди (FIFO) Процессор Очередь

В порядке очереди (FIFO)

Процессор

Очередь

Слайд 14

Циклический алгоритм (Round robin) Очереди Процессор Обслуженные заявки Заявки, обслуживание которых не закончено Порядок просмотра очередей

Циклический алгоритм (Round robin)

Очереди

Процессор

Обслуженные заявки

Заявки, обслуживание которых не закончено

Порядок просмотра очередей

Слайд 15

Процессы и потоки Многопоточность - способность ОС поддерживать в рамках одного

Процессы и потоки

Многопоточность - способность ОС поддерживать в рамках одного процесса

выполнение нескольких потоков.
Поток имеет состояния, контекст, стек, локальную память.
Поток выполняется в адресном пространстве процесса.
Слайд 16

Один поток Несколько потоков

Один поток

Несколько потоков

Слайд 17

Блок управления процессом Адресное пространство Поток 1 Поток 2 Процесс

Блок управления процессом

Адресное пространство

Поток 1

Поток 2

Процесс

Слайд 18

Параллельные процессы Взаимодействующие процессы имеют информационные связи и используют общие ресурсы

Параллельные процессы

Взаимодействующие процессы имеют информационные связи и используют общие ресурсы
Критический ресурс

не допускает одновременное использование несколькими процессами
Слайд 19

Конкурирующие процессы Процесс 1 Процесс 2 Критический ресурс Критическая секция Освобождение Освобождение Блокировка

Конкурирующие процессы

Процесс 1

Процесс 2

Критический ресурс

Критическая секция

Освобождение

Освобождение

Блокировка

Слайд 20

Блокирующие переменные F==1 нет да F=0 F=1 Проверка занятости Занять ресурс

Блокирующие переменные

F==1

нет

да

F=0

F=1

Проверка занятости

Занять ресурс

Критическая секция

Освободить ресурс

F – блокирующая переменная

Слайд 21

Семафоры Дейкстры S – семафор P(S) – операция закрытия (проверки) V(S)

Семафоры Дейкстры

S – семафор
P(S) – операция закрытия (проверки)
V(S) – операция открытия

(увеличения)
P(S): if S>0 then S:=S-1;
else WAIT(S) {перевести процесс в очередь ожидания к семафору S}
V(S): if есть процессы, ожидающие семафор S
then
RELEASE(S) {перевести один из процессов очереди S в очередь готовности}
else
S:=S+1;
Слайд 22

Взаимное исключение var S: semafore; begin S:=1; parbegin ПР1: begin P(S);

Взаимное исключение

var S: semafore;
begin
S:=1;
parbegin
ПР1:
begin
P(S);
{критическая секция}
V(S);
end
ПР2:
begin
P(S);
{критическая секция}
V(S);
end
parend
end

Слайд 23

Производитель - потребитель Писатели Читатели Читатели - писатели

Производитель - потребитель

Писатели

Читатели

Читатели - писатели

Слайд 24

var S_св, S_зап , S_иск; begin S_св:=1; S_зап:=0; S_иск:=1; parbegin ПРОИЗВОДИТЕЛЬ:

var S_св, S_зап , S_иск;
begin
S_св:=1;
S_зап:=0;
S_иск:=1;
parbegin
ПРОИЗВОДИТЕЛЬ:
while true do
begin
{подготовка сообщения}
P(S_св);
P(S_иск);
{запись сообщения}
V(S_зап);
V(S_иск);
end
and

Слайд 25

ПОТРЕБИТЕЛЬ: while true do begin P(S_зап); P(S_иск); {прием сообщения} V(S_св); V(S_иск); {обработка сообщения} end parend end

ПОТРЕБИТЕЛЬ:
while true do
begin
P(S_зап);
P(S_иск);
{прием сообщения}
V(S_св);
V(S_иск);
{обработка сообщения}
end
parend
end

Слайд 26

"Читатели – писатели" с приоритетом читателей var R,W: semaphore; NR: integer;

"Читатели – писатели" с приоритетом читателей
var R,W: semaphore;
NR: integer;
procedure ЧИТАТЕЛЬ;
begin

P(R);
NR:=NR+1;
if NR = 1 then P(W);
V(R);
Read_Data; {критический интервал}
P(R);
NR:=NR-1;
if NR = 0 then V(W);
end;
Слайд 27

procedure ПИСАТЕЛЬ; begin P(W); Write_Data; V(W); end begin NR:=0; InitSem(R,1); InitSem(W,1);

procedure ПИСАТЕЛЬ;
begin
P(W);
Write_Data;
V(W);
end
begin
NR:=0;
InitSem(R,1); InitSem(W,1);
parbegin


while true do ЧИТАТЕЛЬ
and
while true do ЧИТАТЕЛЬ
and
………………….
Слайд 28

while true do ЧИТАТЕЛЬ and while true do ПИСАТЕЛЬ and while

while true do ЧИТАТЕЛЬ
and
while true do ПИСАТЕЛЬ

and
while true do ПИСАТЕЛЬ
and
………………….
while true do ПИСАТЕЛЬ
parend
end.
Слайд 29

Счетные семафоры (Читатели-писатели) var S: sevmafore; Q,R: integer; begin R:=1; Q:=n;

Счетные семафоры (Читатели-писатели)
var S: sevmafore;
Q,R: integer;
begin R:=1; Q:=n; {Инициализация}
parbegin

ЧИТАТЕЛЬ: do
{……….}
P(S,R);
{Чтение}
V(S,R);
end;
Слайд 30

ПИСАТЕЛЬ: do {…………..} P(S,Q); {запись} V(S,Q); end; parend end

ПИСАТЕЛЬ: do
{…………..}
P(S,Q);
{запись}
V(S,Q);
end;
parend
end

Слайд 31

Обедающие философы

Обедающие философы

Слайд 32

Множественные семафоры var S: array 1..5 of semaphore; i: integer; begin

Множественные семафоры

var S: array 1..5 of semaphore;
i: integer;
begin
i:=5;
repeat

S[i]:=1; i:=i-1; until i=0;
parbegin
1: begin {тело процесса}
…………………………
Слайд 33

i: begin var left, right: 1..5; begin left:=(i-1) mod 5; right:=


i: begin
var left, right: 1..5;
begin
left:=(i-1) mod 5;

right:= (i+1) mod 5;
repeat
{размышления}
P(S[left]; S[right]);
{критическая секция}
V(S[left]; S[right]);
end repeat;
end
end
parend
end
Слайд 34

Тупики Взаимные блокировки (deadlock) П1 П2

Тупики

Взаимные блокировки (deadlock)

П1

П2

Слайд 35

Условия возникновения Взаимные исключения. Одновременно использовать ресурсы может только один процесс.

Условия возникновения

Взаимные исключения. Одновременно использовать ресурсы может только один процесс.
Удержание и

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

Предотвращение тупиков Условие взаимного исключения можно подавить путем неограниченного разделения ресурсов.

Предотвращение тупиков

Условие взаимного исключения можно подавить путем неограниченного разделения ресурсов.
Условие ожидания

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

Процессы в ОС UNIX

Процессы в ОС UNIX

Слайд 38

Виды процессов Системные процессы. Системные процессы – часть ядра. Запускаются при

Виды процессов
Системные процессы.
Системные процессы – часть ядра. Запускаются при инициализации системы.


- управление свопингом.
- буферизация.
- управление памятью и т. д.
особую роль играет системный процесс init – прародитель (инициатор) всех остальных процессов.
Демоны
Специальные процессы, запускаемые при инициализации системы в фоновом режиме. Не имеет связи с пользователями.
- управление системой печати.
- сетевой сервис.
- терминальный доступ и т. д.
Прикладные процессы
Основные процессы системы. Обычно прикладные процессы порождаются сеансами пользователей. Широкий цикл прикладных процессов ограничен сеансом работы пользователя.
Слайд 39

Атрибуты процесса Идентификатор процесса (PID) Идентификатор родительского процесса (PPID) Реальный идентификатор

Атрибуты процесса

Идентификатор процесса (PID)
Идентификатор родительского процесса (PPID)
Реальный идентификатор пользователя (RID)


Эффективный идентификатор пользователя (EUID)
Реальный идентификатор группы (RGID )
Эффективный идентификатор группы (EGID)
Идентификатор группы процесса (PGID)
Идентификатор сеанса (SID)
Приоритет процесса (Nice Number)
Текущий каталог
Корневой каталог
Слайд 40

Дескриптор процесса Таблица процессов Блок управления процессом (PCB)

Дескриптор процесса

Таблица процессов

Блок управления процессом (PCB)

Слайд 41

Состояния процесса

Состояния процесса

Слайд 42

Создание и уничтожение процессов #include #include pid_t fork(void);

Создание и уничтожение процессов

#include
#include
pid_t fork(void);

Слайд 43

#include #include #include main() { int pid; pid = fork(); if

#include
#include
#include
main()
{
int pid;
pid = fork();
if (pid

== -1){
perror("fork");
exit (1);}
if (pid == 0)
printf("Дочерний PID=%d \n", pid);
else
printf("Родительский PID=%d \n", pid);
return 0;
}
Слайд 44

#include #include #include #include int main() { int x, pid; x=2;

#include
#include
#include
#include
int main()
{
int x, pid;
x=2;
printf("Один

процесс, x=%d\n",x);
pid=fork();
if(pid == 0)
printf("Дочерний процесс, x=%d\n",x);
else if(pid > 0){
printf("Родительский процесс, pid=%d, x=%d\n",pid,x);
sleep(5);
wait(pid);
}
else {
perror("Ошибка fork()");
return -1;
}
return EXIT_SUCCESS;
}
Слайд 45

Результат выполнения fork() Отводится место в таблице процессов под новый процесс

Результат выполнения fork()

Отводится место в таблице процессов под новый процесс
Порожденному процессу

присваивается идентификатор
Создается логическая копия родительского процесса
Увеличиваются значения счетчика числа файлов, связанных с процессом
Идентификатор порожденного процесса возвращается родительскому процессу
Слайд 46

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

Порожденный процесс наследует

Идентификаторы пользователя и группы
Переменные окружения
Сигналы и их обработчики
Ограничения, накладываемые

на процесс
Текущий и корневой каталоги
Маску создания файлов
Файловые дескрипторы и указатели
Управляющий терминал
Слайд 47

Различия между процессами Порожденный процесс имеет свой идентификатор PID Идентификаторы родительского

Различия между процессами

Порожденный процесс имеет свой идентификатор PID
Идентификаторы родительского процесса PPID

различны
Порожденный процесс не наследует сигналов, ожидающих доставки
Значения, возвращаемые вызовом fork() различно для родителя и потомка
Слайд 48

Завершение процесса Процесс завершается по функции exit. Код нормального завершения 0.

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

Процесс завершается по функции exit. Код нормального завершения 0.
Действия:
Отключаются сигналы.
Сохраняется

код возврата и статистика выполнения.
Процесс переходит в состояние "зомби".
Освобождается адресное пространство процесса и области свопинга.
Родительскому процессу отправляется сигнал SIGCHILD.
Пробуждается ожидающий завершения потомка родительский процесс.
Запускается функция переключения контекста.
Слайд 49

Синхронизация процессов #include pid_t wait(int* status_p); pid_t waitpid(pid_t child_pid, int* status,

Синхронизация процессов

#include
pid_t wait(int* status_p);
pid_t waitpid(pid_t child_pid, int* status, int option);


WNOHANG – неблокирующий вызов (если нет порожденного процесса функция немедленно возвратит управление)
WUNTRACED – ожидание остановленного процесса
Слайд 50

Запуск новой программы Дерево семейства вызовов exec execl execle execlp execv execve execvp

Запуск новой программы

Дерево семейства вызовов exec

execl

execle

execlp

execv

execve

execvp

Слайд 51

Аргументы передаются списком execl(const char* path, const char *arg0,…,const char *argn,

Аргументы передаются списком
execl(const char* path, const char *arg0,…,const char *argn, NULL);

передается полный путь к программе
execlp(const char* file, const char *arg0,…,const char *argn, NULL);
передается только имя файла
execle(const char* path, const char *arg0,…, const char** env);
дополнительно передается указатель на массив переменных окружения
Передается массив аргументов
execv(const char* path, const char *argv[ ]);
передается полный путь к программе
execvp(const char* file, const char *argv[ ]);
передается только имя файла
execve(const char* path, const char ** argv,…,const char** env);
дополнительно передается указатель на массив переменных окружения
Слайд 52

#include #include #include #include #include int main() { pid_t pid; int

#include
#include
#include
#include
#include
int main()
{ pid_t pid;
int

status;
if ((pid=fork())==-1) {
perror("Error fork");
return -1;
}
Слайд 53

if (pid == 0) { printf("Child\n"); execl("/home/sbd/child",NULL); perror("execl"); exit(errno); } else

if (pid == 0) {
printf("Child\n");
execl("/home/sbd/child",NULL);
perror("execl");
exit(errno);
}
else {
printf("Parent\n");
wait(&status);
exit (0);

}
}
Слайд 54

Вызываемая программа #include #include #include int main() { sleep(4); printf("Execut child\n"); exit (0); }

Вызываемая программа
#include
#include
#include
int main()
{
sleep(4);
printf("Execut child\n");
exit (0);
}

Слайд 55

Планирование процессов Таймер Фиксированный тик – интервал между соседними прерываниями. Функции

Планирование процессов

Таймер
Фиксированный тик – интервал между соседними прерываниями.
Функции обработчика прерываний

от таймера:
Обновление статистики использования процессом ЦП
Пересчет приоритетов и проверка истечения кванта
Обновление системного времени и таймеров
Пробуждение системных процессов
Обработка отложенных вызовов
Обработка сигналов alarm
Слайд 56

Функции работы со временем time.h – ANSI C time_t time(time_t *tmv);

Функции работы со временем
time.h – ANSI C
time_t time(time_t *tmv); возвращает количество

секунд, прошедшее с 1.01.1970. Если параметр не NULL, то результат записывается по заданному указателю.
const char* ctime(const time_t *tmv);
Слайд 57

struct tm { int tm_sec; //секунды int tm_min; //минуты int tm_hour;

struct tm {
int tm_sec; //секунды
int tm_min; //минуты
int tm_hour; //часы (от 0 до 24)
int tm_mday; //дни

месяца (от 1 до 31)
int tm_mon; //месяц (от 0 до 11)
int tm_year; // год (после 1900)
int tm_wday; // день недели (Воскресенье = 0)
int tm_yday; // день года (от 0 до 365)
int tm_isdst; //флаг летнего времени (для США)
};
Слайд 58

struct tm* localtime(const time_t *tmv); struct tm* gmtime(const time_t *tmv); time_t mktime(struct tm* tm_ptr); #include

struct tm* localtime(const time_t *tmv);
struct tm* gmtime(const time_t *tmv);
time_t mktime(struct tm*

tm_ptr);
#include
Слайд 59

#include #include #include #include #include int main() { time_t tick= CLOCKS_PER_SEC;

#include
#include
#include
#include
#include
int main()
{
time_t tick= CLOCKS_PER_SEC;
time_t

tmv;
struct tm *tp;
clock_t ctm,etm;
struct tms systime;
ctm = clock(); cout << "Sys time-> "< time(&tmv); cout << "Local time=" << ctime(&tmv) << endl;
tp=localtime(&tmv); cout<<1900+tp->tm_year<<','<tm_mon+1< sleep(2);
times(&systime);
cout<<"Task time->"< cout<<"Nuclear time->"< etm = clock()-ctm; cout<< "Run time="< return EXIT_SUCCESS;
}
Слайд 60

Алармы Таймер реального времени (SIGALARM) - используется для подсчета реального времени

Алармы

Таймер реального времени (SIGALARM) - используется для подсчета реального времени
Таймер

профилирования (SIGPROF) – изменяется , когда процесс находится в состоянии ядра
Виртуальный таймер (SIGVTALARM) – изменяется, когда процесс находится в состоянии задачи
Слайд 61

Операции над процессами Создание процесса Уничтожение процесса Приостановка процесса Возобновление процесса

Операции над процессами

Создание процесса
Уничтожение процесса
Приостановка процесса
Возобновление процесса
Изменение приоритета процесса
Блокирование процесса
Пробуждение процесса
Запуск

(выбор) процесса
Обеспечение взаимодействия процессов
Слайд 62

Взаимодействие процессов (IPC) Сигналы Каналы (pipe) Именованные каналы (FIFO) Сообщения (messages) Семафоры Разделяемая память Сокеты (socket)

Взаимодействие процессов (IPC)

Сигналы
Каналы (pipe)
Именованные каналы (FIFO)
Сообщения (messages)
Семафоры
Разделяемая память
Сокеты (socket)

Слайд 63

Сигналы Генерация сигнала Особые ситуации Терминальные прерывания (Del, Ctrl+C…) Другие процессы

Сигналы

Генерация сигнала
Особые ситуации
Терминальные прерывания (Del, Ctrl+C…)
Другие процессы (вызов kill)
Управление заданиями
Квоты
Уведомления
Алармы


Слайд 64

Доставка и обработка сигнала Ядро от имени процесса проверяет наличие сигнала

Доставка и обработка сигнала

Ядро от имени процесса проверяет наличие сигнала
Если сигнал

есть, ядро обрабатывает его по умолчанию, либо запускает специальную функцию, которая вызывает специальную функцию обработки сигнала.
kill [сигнал] pid1, pid2,…
kill –l вывод списка идентификаторов сигналов
#include
#include
int kill(pid_t pid, int sig_num);
Слайд 65

#include #include #include #include // Handler void my_hand() {cout int main()

#include
#include
#include
#include
// Handler
void my_hand()
{cout << "Handler\n";}
int main()
{
struct

sigaction act, old_act;
cout << "Server" << endl;
act.sa_handler = my_hand;
if (sigaction(SIGUSR1, &act, &old_act) == -1)
perror("Sigaction\n");
pause(); //
return 0;
}
Слайд 66

// Формирование сигнала #include #include #include int main() { int pid;

// Формирование сигнала
#include
#include
#include
int main()
{
int pid;
cout <<

"Input PID: ";
cin >> pid;
cout << "Send signal\n" << endl;
kill(pid, SIGUSR1);
return 0;
}
Слайд 67

Неименованные каналы (pipe) #include Int pipe(int fd[2]); процесс fd[1] fd[0] канал процесс ядро

Неименованные каналы (pipe)

#include
Int pipe(int fd[2]);

процесс

fd[1]

fd[0]

канал

процесс

ядро

Слайд 68

Канал после вызова fork()

Канал после вызова fork()

Слайд 69

Родительский процесс Дочерний процесс fork Канал Односторонний канал

Родительский процесс

Дочерний процесс

fork

Канал

Односторонний канал

Слайд 70

#include #include #include #include #include int main() { pid_t childPid; int

#include
#include
#include
#include
#include
int main()
{
pid_t childPid;
int flds[2],

status;
char buf[]="Message";
if (pipe(flds) == -1) {
perror("Pipe"); exit(1);
}
switch (childPid=fork()) {
case -1: perror("fork"); exit(2);
case 0: close(flds[0]);
printf("Child process %d\n", getpid());
write(flds[1], buf, strlen(buf));
close(flds[1]); exit(0);
}
close(flds[1]);
read(flds[0], buf, 80);
printf("String -> %s\n", buf);
close(flds[0]);
wait(&status); return status;
}
Слайд 71

who | sort | lp who sort lp Канал 1 Канал 2 stdout stdout stdin stdin

who | sort | lp

who

sort

lp

Канал 1

Канал 2

stdout

stdout

stdin

stdin

Слайд 72

родительский процесс дочерний процесс Канал 1 Канал 2 fd2[0] fd1[1] fd1[0]

родительский процесс

дочерний процесс

Канал 1

Канал 2

fd2[0]

fd1[1]

fd1[0]

fd2[1]

Двусторонняя передача по двум каналам

Слайд 73

Именованные каналы #include #include int mkfifo(const char *pathname, mode_t mode); При

Именованные каналы

#include
#include
int mkfifo(const char *pathname, mode_t mode);
При успешном звершении

возвращается 0, в случае ошибки возвращается -1.
S_IRUSR – чтение для владельца
S_IWUSR – запись для владельца
S_IRGRP – чтение для членов группы
S_IWGRP – запись для членов группы
S_IROTH – чтение для прочих пользователей
S_IWOTH – запись для прочих пользователей
Слайд 74

Логика открытия объекта IPC

Логика открытия объекта IPC

Слайд 75

#include #include #include #include #include #include #define NAME " fifo_s.cc" int

#include
#include
#include
#include
#include
#include
#define NAME " fifo_s.cc"
int main()
{
int

fd;
char buf[80];
if(mkfifo(NAME, S_IFIFO|S_IRWXU|S_IRWXG|S_IRWXO)) {
perror("Ошибка FIFO"); return 1;
}
if((fd=open(NAME, O_RDONLY))==-1) {
perror("Ошибка открытия файла"); return 2;
}
read(fd, buf, sizeof(buf));
cout<<"Получено->"< close(fd);
return 0;
}
Слайд 76

#include #include #include #include #include #include #include #include #define NAME "

#include
#include
#include
#include
#include
#include
#include
#include
#define NAME "

fifo_s.cc"
int main()
{
char text[80];
int fd;
cout<<"Ввести текст-"< cin>>text;
if((fd=open(NAME, O_RDWR))==-1) {
perror("Ошибка открытия файла");
return 1;
}
write(fd, text, strlen(text));
close(fd);
return 0;
}
Слайд 77

Создание ключей #include #include key_t ftok(const char *pathname, int id); Возвращает

Создание ключей

#include
#include
key_t ftok(const char *pathname, int id);
Возвращает ключ, в

случае ошибки возвращает -1.
Если нужен один канал,
то
id = 1,
иначе
идентификаторы должны быть разными (1 и 2)
Слайд 78

#include #include #include #include int main() { key_t key; if((key =

#include
#include
#include
#include
int main()
{
key_t key;
if((key = ftok("main.c",0))==-1)

printf("Error 1\n");
printf("key1->%x\n",key);
if((key = ftok("main.c",0))==-1)
printf("Error 2\n");
printf("key2->%x\n",key);
if((key = ftok("Makefile",0))==-1)
printf("Error 3\n");
printf("key3->%x\n",key);
return EXIT_SUCCESS;
}
key1->77b7d
key2->77b7d
key3->77b80
Слайд 79

Управляющая структура IPC struct ipc_perm { uid_t uid; //идентификатор пользователя владельца

Управляющая структура IPC

struct ipc_perm {
uid_t uid; //идентификатор пользователя владельца
gid_t gid; //идентификатор группы владельца
uid_t

cuid; //идентификатор пользователя создателя
gid_t cgid; //идентификатор группы создателя
mode_t mode; //разрешение чтения-записи
ulong_t seq; //последовательный номер канала
key_t key; //ключ IPC
};
Идентификатор создателя изменяться не может
Идентификатор владельца может изменяться функцией управления
Слайд 80

Сообщения (messages) Ядро Процесс А Процесс Г Процесс Б Процесс В

Сообщения (messages)

Ядро

Процесс А

Процесс Г

Процесс Б

Процесс В

А-В

А-В

А-Г

А-Г

В-Б

В-Б

Слайд 81

Очереди сообщений Таблица сообщений Заголовок очереди msgid_ds Область памяти ядра msg_perm

Очереди сообщений

Таблица сообщений

Заголовок очереди msgid_ds

Область памяти ядра

msg_perm
msg_first msg_last

ipc_perm

struct msg

msg_next

msg_next

msg_spot

msg_spot

Слайд 82

Структуры данных struct msgid_ds

Структуры данных

struct msgid_ds

Слайд 83

struct msg

struct msg

Слайд 84

Функции #include #include #include #include int msgget(key_t key, int flag); int

Функции

#include
#include
#include
#include
int msgget(key_t key, int flag);
int msgsnd(int

msgfd, const void* msgPtr, int len, int flag);
int msgrcv(int msgfd, const void* msgPtr, int len, int mtype, int flag);
int msgctl(int msgfd, int cmd, struct msgid_ds* mbufPtr);
cmd
IPC_STAT – копировать управляющие параметры
IPC_SET – заменить управляющие параметры
IPC_RMID – удалить очередь
Слайд 85

/* mes.h */ #define PERM 0666 typedef struct msgbuf { long mtype; char buff[80]; } Message;

/* mes.h */
#define PERM 0666
typedef struct msgbuf {
long mtype;
char buff[80];
} Message;

Слайд 86

#include #include #include #include #include "mes.h" int main() { Message message;

#include
#include
#include
#include
#include "mes.h"
int main()
{
Message message;
key_t key;
int msgid, length,

n;
if((key = ftok("server",0))<0){ printf("Key error\n"); exit(1); }
message.mtype = 1L;
if((msgid = msgget(key,PERM | IPC_CREAT))<0){
printf("Queue error\n"); exit(1);
}
n = msgrcv(msgid, &message, sizeof(message), message.mtype, 0);
if(n>0) {
if(write(1, message.buff, n) != n) {
printf("Output error\n"); exit(1);
}
}
else {printf("Reding error\n"); exit(1);}
exit(0);
}
Слайд 87

#include #include #include #include #include "mes.h" int main() { Message message;

#include
#include
#include
#include
#include "mes.h"
int main()
{
Message message;
key_t key;
int msgid, length;
if((key

= ftok("server",0))<0){
printf("Key error\n"); exit(1);
}
message.mtype = 1L;
if((msgid = msgget(key,0))<0){ printf("Queue error\n"); exit(1);}
if((length = sprintf(message.buff, "Example message\n")) < 0) {
printf("Copy error\n"); exit(1);
}
if(msgsnd(msgid, (void *) &message, length, 0) != 0) {
printf("Write error\n"); exit(1);
}
if(msgctl(msgid, IPC_RMID, 0) < 0) { printf("Delete errror\n"); exit(1);}
exit(0);
}
Слайд 88

Семафоры Таблица семафоров struct sem struct sem sem_base struct semid_ds

Семафоры

Таблица семафоров

struct sem

struct sem

sem_base

struct semid_ds

Слайд 89

struct semid_ds { struct ipc_perm sem_perm; //права доступа struct sem *sem_base;

struct semid_ds {
struct ipc_perm sem_perm; //права доступа
struct sem *sem_base;

//указатель на массив семафоров
ushort sem_nsems; //число семафоров в наборе
time_t sem_otime; //время последней операции над семафором
time_t sem_ctime; //время последнего изменения параметров
};
struct sem {
ushort semval; //целочисленное значение семафора
pid_t semid; //процесс, выполнявший операции над семафором в последний раз
ushort semncnt; //число ожидающих увеличения семафора процессов
ushort semzcnt; //число процессов, ожидающих обращения семафора в нуль
};
Слайд 90

#include #include #include int semget(key_t key, int num_sem, int flag); flag

#include
#include
#include
int semget(key_t key, int num_sem, int flag);
flag –

SEM_R или SEM_A (R - read, A – Alter изменение)
int semop(int semfd, struct sembuf* opPtr, int len);
struct sem_buf {
short sem_num; //индекс семафора
short sem_op; //операция над семафором
short sem_flg; //флаги операции
};
Слайд 91

int semctl(int semfd; int num, int cmd, union semun arg); union


int semctl(int semfd; int num, int cmd, union semun arg);
union

semun {
int val; //значение семафора
struct semid_ds *buf; //управляющие параметры семафора
ushort *array; //массив значений семафора
};
Слайд 92

sem_op > 0 => v(s) semval = semval + sem_op Если

sem_op > 0 => v(s)
semval = semval + sem_op
Если есть процессы,

ожидающие изменения этого семафора, то они продолжат выполнение, когда новое значение удовлетворит их условия.
sem_op = 0
Ожидание пока семафор не станет равным 0.
Слайд 93

sem_op p(s) if (semval >= abs(sem_op)) semval = semval – abs(sem_op)

sem_op <0 => p(s)
if (semval >= abs(sem_op))
semval = semval – abs(sem_op)
else
if

(sem_flg & IPC_NOWAIT)
вернуть -1
else {
ожидание пока semval не станет >= abs(sem_op)
затем semval = semval – abs(sem_op)
}
Слайд 94

Разделяемая память Пространство пользователя Пространство ядра общая память

Разделяемая память

Пространство пользователя

Пространство ядра

общая память

Слайд 95

Процесс 1 Процесс 2 Память shmget() shmat() shmat()

Процесс 1

Процесс 2

Память

shmget()

shmat()

shmat()

Слайд 96

struct shmid_ds { struct ipc_perm shm_perm; // режим и права доступа

struct shmid_ds {
struct ipc_perm shm_perm; // режим и права доступа

size_t shm_size; //размер сегмента
pid_t shm_lpid; //процесс, выполнивший последнюю операцию
pid_t shm_cpid; //процесс создатель
shmatt_t shm_nattch; //текущее количество подключений
shmatt_t shm_cnattch; //количество подключений in-core
time_t shm_atime; //время последнего подключения
time_t shm_dtime; //время последнего отключения
time_t shm_ctime; //время последнего изменения shmid_ds
};
Слайд 97

Функции #include int shmget(key_t key, size_t size, int shmflag); void *shmat(int

Функции

#include
int shmget(key_t key, size_t size, int shmflag);
void *shmat(int shmid,

const void *shmaddr, int flag);
по умолчанию следует задавать shmaddr равный NULL
память доступна для чтения и записи, при необходимости следует использовать флаг RDONLY
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buff);
IPC_RMID – удаление сегмента разделяемой памяти
IPC_SET – установка полей shmid_ds по содержимому buff
IPC_STAT – копировать shmid_ds в buff
Слайд 98

/* share.h */ #include #include #include #include #include #include #define SHMKEY1

/* share.h */
#include
#include
#include
#include
#include
#include
#define SHMKEY1 (key_t)010
#define

SHMKEY2 (key_t)015
#define SEMKEY (key_t)020
#define SIZ 5*BUFSIZ
struct databuf {
int d_nread;
char d_buf[SIZ];
};
typedef union semun {
int val;
struct semid_ds *buf;
ushort *array;
} semun;
Слайд 99

#include "share.h" #define IFLAGS (IPC_CREAT | IPC_EXCL) #define ERR ((struct databuf

#include "share.h"
#define IFLAGS (IPC_CREAT | IPC_EXCL)
#define ERR ((struct databuf *) -1)
static

int shmid1, shmid2, semid;
struct sembuf p1 = {0,-1,0}, p2 = {1,-1,0};
struct sembuf v1 = {0,1,0}, v2 = {1,1,0};
void getseg(struct databuf **p1, struct databuf **p2)
{
if((shmid1 = shmget(SHMKEY1, sizeof(struct databuf), 0600|IFLAGS))==-1)
{perror("shmget1"); exit(1);}
if((shmid2 = shmget(SHMKEY2, sizeof(struct databuf), 0600|IFLAGS))==-1)
{perror("shmget2"); exit(1);}
if((*p1 = (struct databuf *)shmat(shmid1, 0, 0)) == ERR)
{perror("shmatt1"); exit(1);}
if((*p2 = (struct databuf *)shmat(shmid2, 0, 0)) == ERR)
{perror("shmatt1"); exit(1);}
}
Слайд 100

int getsem(void) { union semun x; x.val = 0; if((semid =

int getsem(void)
{
union semun x;
x.val = 0;
if((semid = semget(SEMKEY,

2, 0600|IFLAGS))==-1)
{perror("semget"); exit(1);}
if(semctl(semid, 0, SETVAL, x)==-1)
{perror("semctl"); exit(1);}
if(semctl(semid, 1, SETVAL, x)==-1)
{perror("semct2"); exit(1);}
return (semid);
}
void remobj(void)
{
if(shmctl(shmid1, IPC_RMID, NULL)==-1)
{perror("shmctl3"); exit(1);}
if(shmctl(shmid2, IPC_RMID, NULL)==-1)
{perror("shmctl4"); exit(1);}
if(semctl(semid, 0, IPC_RMID, NULL)==-1)
{perror("semctl"); exit(1);}
}
Слайд 101

void reader(int semid, struct databuf *buf1, struct databuf *buf2) { for(;;)

void reader(int semid, struct databuf *buf1, struct databuf *buf2)
{
for(;;) {
buf1->d_nread=read(0,buf1->d_buf, SIZ);
semop(semid,

&v1, 1);
semop(semid, &p2, 1);
if(buf1->d_nread<=0) return;
buf2->d_nread = read(0,buf2->d_buf,SIZ);
semop(semid, &v2, 1);
semop(semid, &p1, 1);
if(buf2->d_nread<=0) return;
}
}
Слайд 102

void writer(int semid, struct databuf *buf1, struct databuf *buf2) { for(;;)

void writer(int semid, struct databuf *buf1, struct databuf *buf2)
{
for(;;) {
semop(semid, &p1,

1);
semop(semid, &v2, 1);
if(buf1->d_nread <= 0) return;
write(1, buf1->d_buf, buf1->d_nread);
semop(semid, &p2, 1);
semop(semid, &v1, 1);
if(buf2->d_nread <= 0) return;
write(1, buf2->d_buf, buf2->d_nread);
}
}
Слайд 103

main() { int semid; pid_t pid; struct databuf *buf1, *buf2; semid

main()
{
int semid;
pid_t pid;
struct databuf *buf1, *buf2;
semid = getsem();
getseg(&buf1, &buf2);
switch(pid = fork())

{
case -1:
perror("fork"); exit(1);
case 0:
writer(semid, buf1, buf2);
remobj();
break;
default:
reader(semid, buf1, buf2);
break;
}
exit(0);
}
Слайд 104

Процессы в ОС Windows

Процессы в ОС Windows

Слайд 105

Особенности процессов Процесс виртуальное адресное пространство; управляющая информация, необходимая для выполнения

Особенности процессов

Процесс
виртуальное адресное пространство;
управляющая информация, необходимая для выполнения набора потоков

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

Потоки Каждый процесс начинается с одного потока, но новые потоки могут

Потоки

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

динамически
Потоки имеют состояния (готовый, работающий, блокированный и т. д.) (у процессов состояний нет)
Поток работает в пользовательском режиме, но когда он обращается к системному вызову, то переключается в режим ядра
Любой поток может получить доступ ко всем объектам его процесса
Слайд 107

Волокна Переключение потоков в операционной системе Windows занимает довольно много времени,

Волокна

Переключение потоков в операционной системе Windows занимает довольно много времени, так

как для этого необходимо переключение в режим ядра
Для предоставления сильно облегченного псевдопараллелизма в Windows используются волокна, планируемые в пространстве пользователя создавшей их программой
У каждого потока может быть несколько волокон
Когда волокно логически блокируется, оно помещается в очередь блокированных волокон, после чего для работы выбирается другое волокно в контексте того же потока.
Операционная система не знает о смене волокон, так как все тот же поток продолжает работу
Так как операционная система ничего не знает о волокнах, то с ними не связаны объекты исполняющей системы
Для управления волокнами нет системных вызовов. Для этого есть вызовы Win32 API. Они относятся к тем вызовам Win32 API, которые не обращаются к системным вызовам
Слайд 108

Создание процесса Открывается файл образа (exe – файл) Создается объект «процесс»

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

Открывается файл образа (exe – файл)
Создается объект «процесс»
Создается первичный поток

(стек, контекст и объект «поток»)
Подсистема Windows уведомляется о создании нового процесса и потока
Начинается выполнение первичного потока
В контексте нового процесса и потока инициируется адресное пространство и начинается выполнение программы
Слайд 109

Новый процесс создается при помощи функции CreateProcess Функция имеет 10 параметров:

Новый процесс создается при помощи функции CreateProcess
Функция имеет 10 параметров:
1.

Указатель на имя исполняемого файла.
2. Сама командная строка (непроанализированная).
3. Указатель на описатель защиты процесса.
4. Указатель на описатель защиты для начального потока.
5. Бит, управляющий наследованием дескрипторов.
6. Разнообразные флаги (например, режим ошибки, приоритет, отладка, консоли).
7. Указатель на строки окружения.
8. Указатель на имя текущего рабочего каталога нового процесса.
9. Указатель на структуру, описывающую начальное окно на экране.
10. Указатель на структуру, возвращающую вызывающему процессу 18 значений.
Слайд 110

В операционной системе Windows не поддерживается какой-либо иерархии процессов, например «родительский

В операционной системе Windows не поддерживается какой-либо иерархии процессов, например

«родительский - дочерний».
Все созданные процессы равны
Один из 18 параметров, возвращаемых вызывающему процессу, представляет собой дескриптор нового процесса (что предоставляет контроль над новым процессом)
Существует негласная иерархия, заключающаяся в том, кто чьим дескриптором владеет
Эти дескрипторы не могут напрямую передаваться другим процессам
У процесса есть способ создать дубликат дескриптора. Дубликат дескриптора может быть передан другому процессу и использоваться им, поэтому неявная иерархия процессов может просуществовать недолго.
Слайд 111

Создание потока Каждый процесс в Windows создается с одним потоком Процесс

Создание потока

Каждый процесс в Windows создается с одним потоком
Процесс может позднее

создать дополнительные потоки
Создание потока производится вызовом CreateThread с шестью параметрами:
1. Описатель защиты (необязательный).
2. Начальный размер стека.
3. Адрес запуска.
4. Параметр, задаваемый пользователем.
5. Начальное состояние потока (готовый или блокированный).
6. Идентификатор потока.
Слайд 112

Планирование процессов В операционной системе Windows нет центрального потока планирования. Когда

Планирование процессов

В операционной системе Windows нет центрального потока планирования.
Когда какой-либо

поток не может более выполняться, этот поток сам переходит в режим ядра и запускает планировщика
Текущий поток выполняет программу планировщика при одном из следующих условий:
1) поток блокируется на семафоре, мьютексе, событии, операции ввода-вывода и т. д;
2) поток сигнализирует каким-либо объектом (например, выполняет операцию up на семафоре);
3) истекает квант времени работающего потока.
Планировщик также вызывается при еще двух условиях:
Завершается операция ввода-вывода.
Истекает ожидание таймера.
Слайд 113

Приоритеты процессов Классы приоритетов реального времени высокий выше нормы нормальный ниже

Приоритеты процессов

Классы приоритетов
реального времени
высокий
выше нормы
нормальный
ниже нормы
неработающий

Приоритеты потоков
критичный ко времени
самый высокий
выше

нормы
нормальный
ниже нормы
самый низкий
неработающий
Слайд 114

Взаимодействие процессов каналы байтовый режим режим сообщений именованные каналы почтовые ящики

Взаимодействие процессов

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

Слайд 115

Механизмы синхронизации семафоры мьютексы критические секции события

Механизмы синхронизации

семафоры
мьютексы
критические секции
события