Правильно для маленькой программы и недопустимо для большой системы. • Аналогия: строительство будки для собаки и строительство небоскрёба

Вид материалаПрограмма
N: Созданная производителем продукция поступает на склад. Склад может хранить N
P1 , потребитель извлекает продукцию с периодом P
Возможность блокирования задачи в течение длительного времени
Решает более (менее) важную задачу чем другие
42)Иерархия памяти. Виртуальная память и управление ею. Иерархия памяти(РИС)
D показывает направление изменения характеристикю. Виртуальная память.(РИС)
Подобный материал:
1   2   3   4
SIGKILL и SIGSTOP нельзя заблокировать или игнорировать.

Для них нельзя определить пользовательский обработчик.

• Посылка сигнала sig процессу с идентификатором pid осуществляется с

помощью системного вызова kill:

int kill(pid_t pid, int sig);

• Пример программы, завершающейся не позднее чем через 3 секунды,

после своего запуска.

Базовые операции над потоками.

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

библиотеку – libpthread. Заголовочный файл: pthread.h

• Для ссылки на поток используется дескриптор потока типа pthread_t.

• Создание нового потока выполняется функцией pthread_create со

следующим прототипом:

int pthread_create(pthread_t * thread, pthread_attr_t * attr,

void * (*start_routine)(void *), void * arg);

• Выполнение потока состоит в выполнении заданной функции start_routine,

которой в качестве параметра передаётся указанное значение arg. Параметр

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

• Поток завершается либо по завершении выполнения своей функции, либо

по выполнении им специальной функции завершения потока pthread_exit со

следующим прототипом:

void pthread_exit(void *retval);

• По завершении потока его дескриптор и стек не освобождаются до тех пор,

пока какой-либо другой поток об этом не узнает. Ожидание завершения

требуемого потока реализуется через функцию pthread_join со следующим

прототипом:

int pthread_join(pthread_t th, void **thread_return);

• Указанная функция должна быть вызвана для каждого из потоков во

избежание утечки памяти и других ресурсов.

36)Задача «разделение доступа к ресурсу».Способы ее решения.

• В примере учёта поступающих средств для обеспечения надёжной работы

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

разделяемому ресурсу – счётчику.

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

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

доступа к ресурсу.

• Участок в программе, в котором осуществляется доступ к разделяемому

ресурсу называется критической секцией ресурса.

• Если один процесс находится в своей критической секции определённого

ресурса, то остальные не должны иметь возможности войти в их

критические секции, относящиеся к тому же самому ресурсу.

• Обеспечение взаимоисключения – необходимость отслеживать попытки

входа процессов в свои критические секции (операция entercritical) и выхода

из них (операция leavecritical).

• При выполнении entercritical процесс может блокироваться до

освобождения ресурса. При выполнении leavecritical, один из процессов

ожидающих входа, возобновляет свою работу.

• Требование к реализации операций entercritical и leavecritical – их

атомарность.

37)Задачи «синхронизация по готовности данных»Понятие

семафора.

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

помощью семафоров.

• Семафор S – защищённая переменная, значение которой можно

опрашивать и менять только специальными операциями P и V, а также

операцией инициализации. Множество значений семафора: неотрицательные

целые числа.

• Операция инициализации: определяет начальное значение семафора.

• Операция P(S): значение семафора уменьшается на 1, если оно

положительно или поток блокируется, если значение семафора нулевое.

• Операция V(S): пробуждение одного из потоков, ожидающих на семафоре,

или увеличение значения на 1, если таковых нет.

• При входе в критическую секцию поток должен выполнять операцию P(S),

а при выходе – V(S).

• Расширение операции P (неблокирующий вариант) – P'(S) : при нулевом

значении семафора немедленно возвращается признак отказа в доступе.

• Для удобной и надёжной работы с семафорами полезно определить

wrapper-класс (класс-обёртку) Semaphor.

//semaphor.h

#ifndef SEMAPHOR_H

#define SEMAPHOR_H

#include

class Semaphor{

public:

Semaphor(int initValue);

~Semaphor();

void wait();

void post();

bool trywait();

private:

sem_t semaphore;

};

#endif

Примеры использования семафоров.РИС

• Задача однократного обмена данными между двумя потоками,

производителем и потребителем. Производитель формирует данные, которые

нужны потребителю в определённый момент его выполнения для

продолжения работы.

• Синхронизация необходима только для потребителя. Он должен дождаться

готовности данных.

• Для решения достаточно одного семафора CanRead (признак наличия

данных в буфере Data) с начальным значением 0 («отсутствие данных»).

Задача «производитель-потребитель» для случая многократного обмена

данными (рис 22).

• Необходима синхронизация и для производителя. Ему необходимо знать,

что потребитель произвёл считывание предыдущих данных из буфера.

• Для решения достаточно двух семафоров CanRead (признак наличия

данных в буфере Data) с начальным значением 0 («отсутствие данных») и

CanWrite (буфер свободен для занесения) с начальным значением 1.

39) Мониторы Хоара. Пример проектирования монитора _склад_ для

Задачи производитель—потребитель. (РИС)

Явное использование мьютексов и семафоров.

• Мьютексы и семафоры решают задачи взаимоисключения и

синхронизации.

• Они представляют средства низкого уровня (аналог языка Ассемблера для

программирования) – требуют тщательного анализа и подвержены

ошибочному использованию.

• Типичный случай №1: использование ресурса без выполнения входа в

критическую секцию, что приводит к нарушению состояния ресурса.

• Типичный случай №2: не выполнение выхода из критической секции, что

влечёт невозможность использования ресурса кем-либо ещё.

• Типичный случай №3: использование средств синхронизации не по

назначению, что разрушает взаимодействие потоков с непредсказуемыми

последствиями.

• Типичный случай №4: вложенное использование, которое приводит поток

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

освободить его может только он сам.

Понятие монитора

• В рассмотренной ранее схеме каждый поток отвечает за решение двух

задач: функциональной и обеспечения синхронизации с другими потоками.

Отсюда проблема. Её решение – избавление от одной из ответственностей.

Поток не должен непосредственно обеспечивать синхронизацию.

• Проблема устраняется при переходе к высокоуровневым средствам

обеспечения взаимоисключения.

• Как правило в задаче известен допустимый набор операций над

разделяемым ресурсом.

• Осуществляется инкапсуляция набора операций в специальный класс –

монитор.

• Переменные состояния монитора определяют ресурс.

• Доступ через методы класса к операциям над ресурсом, но не к самому

ресурсу.

• Преимущества: непосредственное использование ресурса сосредоточено в одном месте. Легче контролировать, обеспечить надёжное манипулирование

ресурсом.

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

• Постановка задачи «производитель-потребитель» со складом вместимости

N: Созданная производителем продукция поступает на склад. Склад может

хранить N экземпляров продукта. При достижении количества N склад

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

извлекает один или несколько потребителей. Они запрашивают по одному

экземпляру. Если продукции нет, то ждут ее поступления.

• Операции: «добавить экземпляр на склад», «взять экземпляр из склада»,

«очистить склад от продукции».

• Для представления склада удобно использовать контейнер «список».

Вместимость склада зададим константой.

• Для определения возможности помещения экземпляра продукции на склад

используем семафор «количество свободных мест» freeCount.

• Для определения наличия продукции на складе используем семафор

«количество экземпляров» productsCount.

• Пример использования: производитель создает продукцию с периодом P1 ,

потребитель извлекает продукцию с периодом P2 .

• Для обеспечения исключительного доступа к складу используем мьютекс

resourceAccess.

//storemonitor.h

#ifndef STOREMONITOR_H

#define STOREMONITOR_H

#include "semaphor.h"

#include "mutex.h"

#include

class StoreMonitor

{

public:

//конструктор очереди заданной вместимости

StoreMonitor(int capacity);

~StoreMonitor() {}

void push(double product); //добавить продукт на склад

void pop(double& product); //извлечь продукт со склада

void clear(); //очистить склад от продукции

private:

std::list container;

Semaphor freeCount; //количество свободных мест на складе

Semaphor productsCount; //количество экземпляров продукции на складе

Mutex resourceAccess; //исключительный доступ к состоянию склада

};

#endif

40)Проектирование и модели многопоточных приложений.

Критерии выполнения задачи в отдельном потоке.

Независимость от других задач: раздельные ресурсы, минимум в

потребности синхронизации.

Возможность блокирования задачи в течение длительного времени:

операция ввода-вывода, ожидание события.

Интенсивное использование центрального процессора: длительные

вычисления.

Необходимость реакции на наступление асинхронных событий: сетевое

взаимодействие, прерывания от аппаратуры или ОС.

Решает более (менее) важную задачу чем другие: ограничение по времени

выполнения, включение в определенные моменты или через заданные

интервалы.

• Примеры задач, кандидатов на отдельный поток: серверные программы,

вычислительные и приложения ЦОС на мультипроцессорных системах,

задачи для выполнения в реальном времени.

• Главная проблема проектирования: распределение задач между потоками и

их взаимодействие.

Модель «начальник - подчиненный».(РИС)

• Существует главный поток («начальник»), который управляет набором

подчинённых ему потоков: порождает их, обеспечивает приём данных и

выставляет задачи подчинённым.

• Задача подчинённых: выполнение обработки данных (поставленных

«начальником» задач).

• Варианты модели подчинённых (рис 24): специализированные (каждый

может решать определённую задачу или многопрофильные (каждый может

выполнять любой допустимый класс задач).

• Набор подчинённых может быть предопределён или «начальник» может

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

• Применение – серверные приложения.

• Пример: «система с множественными потребителями данных».

Модель «без лидера».(РИС)

• Все потоки равноправны. Каждый ответственен за свой ввод.

• Применение – строго определенный набор источников поступления

информации.

• Пример: «система с множественными источниками данных» с вариантами

– однородная или неоднородная по данным, независимая или совместная по

обработке (рис 25).

Модель «конвейер».(РИС)

• Характерные черты: большой поток данных, набор последовательных

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

времени могут выполняются над разными порциями (рис 26).

• Аналогии: конвейер по сборке автомобилей, выполнение машинных

инструкций в RISC-процессорах.

• Применение – обработка изображений, обработка текстов.

• Пропускная способность конвейера – по самой медленной стадии.

• Для ускорения обработки используется мультиплексирование – несколько

потоков выполняют одну и ту же стадию (как правило самую медленную).

• Разбиение стадии обработки на две или более последовательных даёт

выигрыш только в многопроцессорной системе. В однопроцессорной

обязательно проигрыш вследствие дополнительных затрат по времени на

передачу данных.

• Время на передачу данных между стадиями оказывает влияние на

максимальную пропускную способность и в многопроцессорных системах.

41)Организация взаимодействия процессов разных вычислительных

Систем.

• Процесс работает в своём собственном адресном пространстве.

Изолированность адресов – ключевая проблема в организации

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

• Для синхронизации процессов и обмена данными между ними

используются стандартные системные средства-ресурсы.

• Время жизни системного ресурса межпроцессного взаимодействия может

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

• Доступ к ресурсам межпроцессного взаимодействия организован через

системные вызовы.

• Передача данных процессом сопровождается копированием данных из

области процесса в системную область.

• Приём данных процессом сопровождается копированием данных из

системной области в область процесса.

Средство организации взаимодействия – каналы(РИС)

• принципы обмена данными посредством канала: поток байтов, «очередь»

• операции над каналами (создание, открытие, чтение, запись, закрытие)

• блокирование процесса при выполнении доступа к каналу.

• непоименованные каналы можно использовать между родственными

процессами. Данные в канале размещаются в оперативной памяти.

Недостаток использования – ограничение на вместимость. Время жизни

канала ограничено временем жизни процессов, использующих его.

• поименованные – между любыми процессами. Данные в канале

размещаются в специальном файле. Время жизни канала может превышать

время жизни процессов, использующих его с сохранением данных в канале.

• использование (в оболочках – реализация конвейера команд)

• системные вызовы: pipe, mknod, open, read, write, close


Организация взаимодействия посредством очередей сообщений.(РИС)

• принципы обмена данными посредством сообщений: структурированный

поток байтов, типы сообщений, ключи (рис 28).

• операции над очередью (создание, открытие, чтение, запись, закрытие)

• блокирование процесса при выполнении доступа к очереди.

• Время жизни очереди сообщений может превышать время жизни

процессов, использующих его с сохранением данных в очереди.

• недостатки использования (ограничение на вместимость, накладные

расходы)

• системные вызовы: ftok, msgget, msgsnd, msgrcv, msgctl

Разделяемая память.(РИС)

• Принципы обмена данными через разделяемую память: «перекрытие»

адресного пространства, ключи (рис 29).

• Операции (создание-открытие, присоединение, отсоединение)

• сравнение с общей памятью потоков выполнения (существует после

завершения процессов, явное присоединение, уникальные ключи).

• системные вызовы: ftok, shmget, shmat, shmdt, shmctl


Семафоры (System V)

• Используются как средство синхронизации процессов.

• Системный ресурс, существующий вне процессов.

• Через системные вызовы предоставляют операции создания, P(S), V(S) и

инициализации.

• Использование – совместно с разделяемой памятью.

• Системные вызовы: semget, semop, semctl

Использование сокетов.(РИС)

• Могут использоваться для взаимодействия процессов разных

вычислительных систем

• Сокет идентифицируется указанием IP-адреса вычислительной системы и

номером порта на ней.

• Этапы установления связи со стороны сервера

1. создание окончания (сокета) для соединения (socket);

2. именование сокета с помощью указания адреса (bind);

3. прослушивание в ожидании запроса (listen);

4. принятие (ввод) (accept);

5. выполнение ввода-вывода (read/write);

6. закрытие (close).

• Этапы установления связи со стороны клиента

1. создание окончания (сокета) для соединения (socket);

2. формирование сетевого адреса (inet_pton);

3. запрос на соединение (connect);

4. выполнение ввода-вывода (read/write);

5. закрытие (close).

• Использование – распределенные вычисления, программы просмотра

Internet-сайтов, обмен между приложениями в KDE.

• Полный список сервисов содержится в /etc/services

42)Иерархия памяти. Виртуальная память и управление ею.

Иерархия памяти(РИС)

• Тенденция к удешевлению памяти и увеличению её объёма.

• Для памяти действует закон Паркинсона: «Расходы растут вместе с

доходами».

• Уровни памяти: кэш, основная, вторичная.

• Характеристики памяти: время доступа, стоимость байта, ёмкость.

• На рис 30  D показывает направление изменения характеристикю.

Виртуальная память.(РИС)

• Нехватка оперативной памяти может быть компенсирована

предоставлением процессу возможности использовать адресное

пространство гораздо большее емкости первичной памяти.

• Адресное пространство – это всего лишь диапазон адресов, отведённых

процессу, а не реальное физическое пространство.

• Дополнительную память можно получить за счёт использования

вторичной памяти.

• Основной принцип виртуальной памяти: адреса, к которым обращается

процесс, отделяются от адресов, реально существующих в первичной

памяти.

• Задачи подсистемы виртуальной памяти: обеспечение большого адресного

пространства, защита адресного пространства процессов, отображение

памяти, справедливое распределение, поддержка разделяемой виртуальной

памяти.

43)Организация модулей ядра Linux.

Понятие модуля

• Модуль ядра – это часть кода ядра, которая может быть динамически

загружена и выгружена во время работы ядра.

• Расширяет функциональность ядра без необходимости перезагрузки

системы.

• Позволяет иметь компактное ядро без необходимости его пересборки при

добавлении новой функциональности.

• Получение списка загруженных в ядро модулей – утилита lsmod.

• Получение информации о модуле – утилита modinfo.

• Загрузка модуля в ядро – утилиты modprobe и insmod.

• Выгрузка модуля из ядра – утилита rmmod.

• Модули могут зависеть друг от друга. Установление зависимостей между

модулями – утилита depmod -a.

• Управление модулями – привилегированная операция и выполняется от

имени суперпользователя (пользователя с именем root).

Сборка модуля

• Модуль собирается относительно исходного кода работающего на целевой

системе ядра.

• Для сборки модуля необходимы заголовочные файлы и настройки для

ядра, в которое он будет загружен.

• Сборка осуществляется с помощью make.

• При сборке предпочтительно использовать Makefile указанного ниже вида.

• оbj-m определяет список модулей ядра для сборки.

• KDIR задаёт расположение исходного кода ядра.

• PWD определяет текущий каталог и расположения исходных текстов

модуля.

• Результатом сборки модуля является файл имя_модуля.ko

obj-m := имя_модуля.o

KDIR := /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

default:

$(MAKE) -C $(KDIR) M=$(PWD) modules

Точка доступа к модулю в /proc

• Через файловую систему /proc можно организовать связь между модулем и

пользовательскими программами.

• Постановка задачи: разработать модуль, который будет выводить

информацию о себе при обращении к нему через /proc.

• Для включения поддержки работы с /proc добавляется заголовочный файл

proc_fs.h.

speaker_read_proc – формирует содержимое файла-точки доступа.

create_proc_read_entry – регистрация точки доступа в /proc.

remove_proc_entry – отмена регистрации точки доступа.

Модули могут создавать файлы устройств, которые доступны

пользовательским программам через /dev.

Через файловую систему /proc можно организовать управление модулем со

стороны пользователя посредством изменения значений переменных модуля.

8)Понятие ссылки.Операции над сылкамии способы применения ссылок.

• Доступ к объекту осуществляется по имени, по указателю, по ссылке.

• Синтаксис доступа по имени: имяОбъекта.имяЧлена

• Объявление указателя на объект: имяКласса* имяУказателя;

• Синтаксис доступа по указателю: имяУказателя->имяЧлена

• При вызове в метод передаётся скрытый параметр – указатель на объект,

для которого был вызван метод. Специальный указатель this хранит адрес

этого объекта.

• Ссылка – альтернативное имя объекта. Объявление ссылки на объект:

имяКласса& имяСсылки = имяОбъекта;

• Способы использования ссылки – создание независимой ссылки, для

передачи параметров в методы, для возврата в качестве результата работы

функции. Преимущества и опасности.

• Пример использования this – возвращение ссылки на объект, для которого

был вызван метод addCoin.

Object Object

Pointer

Ref

//slotmachine.h

#ifndef slotmachine_h

#define slotmachine_h

//Представление абстракции "Торговый автомат" – версия 0.3.2

class SlotMachine {

public:

SlotMachine& addCoin(unsigned coin); //опустить монету

bool canDrink(); //можно получить напиток?

bool getDrink(); //получить напиток

private:

unsigned money; //количество денег

unsigned drinkMoney; //количество денег для порции напитка

};

#endif

//slotmachine.cpp

//Реализация класса "Торговый автомат" – версия 0.3.2

//...

SlotMachine& SlotMachine::addCoin(unsigned coin)

{

money += coin;

drinkMoney += coin;

return *this;

}/

/...

//Пример цепочки вызовов методов для объекта.

#include "slotmachine.h"

int main(int argc, char *argv[])

{

SlotMachine orange;

orange.addCoin(3).addCoin(3).getDrink();

//...

return 0;

}