40гг первые цифровые компьютеры программирование путем коммутации проводов
Вид материала | Документы |
СодержаниеCritical_section cs Декларативная программа Императивная программа Функциональное программирование Логическое программирование |
- Рабочая программа учебной дисциплины «Системы коммутации» Направление подготовки, 204.68kb.
- Неоднородный полупроводниковый носитель информации в переменном магнитном поле, 107.68kb.
- Темы Лекции Практика, 13.65kb.
- Общие принципы построения вычислительных сетей, 1480.56kb.
- Курс лекций "интернет технологии", 1261.62kb.
- А) Представление информации в цифровых автоматах (ЦА), 34.28kb.
- Информатика. Лекции. Краткая история компьютерной техники Первые компьютеры: Z3, Colossus,, 3630.67kb.
- Курс лекций для студентов очного и заочного отделений по специальности 210406 «Сети, 3045.9kb.
- Радумльская средняя школа, 28.4kb.
- Лекция №7. Обобщенная задача коммутации Важной задачей построения сетей ЭВМ является, 67.2kb.
with R do
S
end do;
R – общая переменная;
S – последовательность операторов критического интервала.
Простые критические интервалы
- Использование конструкции позволяет отказаться от явных действий с семафорами: открытие и закрытие их производится автоматически в соответствии с командами, сгенерированными транслятором.
- Отпадает необходимость в проверке правильности расстановки операций над семафорами.
- Транслятор может проверить, что общая переменная используется только внутри критических интервалов, так как мы явно указываем их в программе, следовательно, повышается надежность программ.
- Однако, все остальные недостатки семафоров присущи и простому критическому интервалу.
Мониторы
- Монитор — это программная конструкция, в которой общие данные объединены вместе с множеством процедур, реализующих доступ к этим данным.
- Процедуры монитора обладают следующим свойством: в каждый момент времени только один процесс может активно выполнять мониторную процедуру в данном мониторе.
- Монитор является конструкцией высокого уровня, позволяющей осуществлять взаимно исключающий доступ к общим ресурсам.
- По своей мощности мониторы эквивалентны семафорам — с помощью семафоров и базовых средств языка программирования можно реализовать мониторы и, наоборот, с помощью мониторов смоделировать семафоры.
Преимущества мониторов
- Можно написать и отладить монитор отдельно от процессов, которые им будут пользоваться, так как все обращения к общим ресурсам должны выполняться с помощью мониторных процедур
- Получение более ясных программ, которые легче понимать, отлаживать, модифицировать.
- Гарантируется целостность ресурсов, которые монитор защищает, а правильность его функционирования не может быть нарушена при добавлении содержащего ошибки процесса.
- Транслятор может проверить, чтобы все обращения к общим ресурсам были законными
Аппаратная поддержка критических интервалов
- Запрещение прерываний
- Неделимые операции
Запрещение прерываний
Достоинство
- Простота и эффективность реализации
Недостаток
- Запрещение прерываний может негативно отразиться на работе системы в целом
- Не имеет смысла в многопроцессорных системах
Неделимые операции
- В систему команд современных процессоров входит неделимая команда «проверить и установить»
- За одну неделимую операцию происходит проверка переменной на равенство нулю и ее установка в единицу.
- Если переменная была равна нулю, то результат операции – единица, иначе 0.
Средства для реализации параллельной обработки
- Средства обеспечения работы процессов (описание, создание, завершение, обработка исключений)
- Механизмы, реализующие взаимное исключения и синхронизацию для процессов с общей памятью
- Механизмы передачи сообщений
Механизмы передачи сообщений
- Предназначаются для связи между процессами, не имеющими общего адресного пространства.
- Должны поддерживаться операционной системой или средой, в которой выполняются процессы.
- Наиболее общие:
- Сопрограммы – возможность приостанавливать и продолжать выполнение одного процесса из другого.
- Рандеву – возможность передачи данных между процессами без дополнительного буфера (сначала ожидается готовность процессов к передачи и приему, после этого осуществляется синхронный обмен)
- Специализированные
- Почтовые ящики – передача сообщений между процессами через посредника.
- Порты – возможность менять посредника
- Транспортеры – перенаправление ввода/вывода.
Основные понятия для ОС Windows
- Процесс – экземпляр выполняемой программы, состоит из адресного пространства, в котором располагается код программы и данные.
- Процессы инертны. Чтобы процесс что-либо выполнил в нем нужно создать поток (thread). Именно потоки отвечают за выполнение кода программы.
- Процесс содержит как минимум один поток, который создается автоматически при запуске программы и осуществляет ее выполнение.
- Программа может создавать дополнительные потоки по мере необходимости.
- Потоки одного процесса работают в едином адресном пространстве.
- На однопроцессорных компьютерах операционная система предоставляет последовательно каждому потоку квант времени, на многопроцессорных компьютерах одновременно может выполняться столько потоков, сколько есть процессоров.
Средства синхронизации процессов в С/С++ отсутствуют
- Объекты API (используются функции С)
- Взаимоисключения (mutex)
- События (event)
- Семафоры (semaphore)
- Критические интервалы (critical section)
- Защищенный доступ к переменным
- Классы VCL Borland C++ Builder
- TMultiReadExclusiveWriteSynchronizer
- TCriticalSection
- TEvent
Общие особенности
- Отсутствует какая-либо связь между объектом синхронизации и защищаемым ресурсом
- Гарантируется, что все операции с объектами синхронизации являются неделимыми.
Возможные состояния потоков
- Активен – идет выполнение потока на процессоре.
- Готов – поток готов к выполнению, ждет предоставления процессорного времени.
- Заблокирован – потоку не выделяется процессорное время, он не планируется на выполнение.
Управление потоками в Borland C++ Builder
- Для упрощения работы с потоками в Borland C++ Builder предусмотрен специальный класс TThread.
Взаимоисключения
- Объекты-взаимоисключения (мьютексы, mutex - от MUTual EXclusion) позволяют координировать взаимное исключение доступа к разделяемому ресурсу.
- Сигнальное состояние объекта (т.е. состояние "установлен") соответствует моменту времени, когда объект не принадлежит ни одному потоку и его можно "захватить".
- Состояние "сброшен" (не сигнальное) соответствует моменту, когда какой-либо поток уже владеет этим объектом.
- Доступ к объекту разрешается, когда поток, владеющий объектом, освободит его.
- Для того, чтобы объявить взаимоисключение принадлежащим текущему потоку, надо вызвать одну из ожидающих функций.
- Поток, которому принадлежит объект, может его "захватывать" повторно сколько угодно раз (это не приведет к самоблокировке), но столько же раз он должен будет его освобождать.
Пример использования Mutex
#include
#include
void main() {
DWORD res;
// создаем объект-взаимоисключение
HANDLE mutex = CreateMutex(NULL, FALSE, "APPNAME-MTX01");
// если он уже существует, CreateMutex вернет дескриптор существующего
// объекта, а GetLastError вернет ERROR_ALREADY_EXISTS
// в течение 20 секунд пытаемся захватить объект
cout<<"Trying to get mutex...\n";
cout.flush();
res = WaitForSingleObject(mutex,20000);
if (res == WAIT_OBJECT_0) // если захват удался
{ // ждем 10 секунд
cout<<"Got it! Waiting for 10 secs...\n"; cout.flush();
Sleep(10000);
// освобождаем объект
cout<<"Now releasing the object.\n"; cout.flush(); ReleaseMutex(mutex);
}
// закрываем дескриптор
CloseHandle(mutex);
}
События (Event)
- Объекты-события используются для уведомления ожидающих потоков о наступлении какого-либо события.
- Различают два вида событий - с ручным и автоматическим сбросом.
- Ручной сброс осуществляется функцией ResetEvent. События с ручным сбросом используются для уведомления сразу нескольких потоков.
- При использовании события с автосбросом уведомление получит и продолжит свое выполнение только один ожидающий поток, остальные будут ожидать дальше.
- Функция CreateEvent создает объект-событие.
- SetEvent - устанавливает событие в сигнальное состояние.
- ResetEvent-сбрасывает событие.
- Функция PulseEvent устанавливает событие, а после возобновления ожидающих это событие потоков (всех при ручном сбросе и только одного при автоматическом), сбрасывает его.
- Если ожидающих потоков нет, PulseEvent просто сбрасывает событие.
Семафоры
- Объект-семафор - это фактически объект-взаимоисключение со счетчиком.
- Семафор позволяет "захватить" себя определенному количеству потоков.
- После этого "захват" будет невозможен, пока один из ранее "захвативших" семафор потоков не освободит его.
- Семафоры применяются для ограничения количества потоков, одновременно работающих с ресурсом.
- Объекту при инициализации передается максимальное число потоков, после каждого "захвата" счетчик семафора уменьшается.
- Сигнальному состоянию соответствует значение счетчика больше нуля.
- Когда счетчик равен нулю, семафор считается не установленным (сброшенным).
Критические интервалы
- Объект - критический интервал помогает программисту выделить участок кода, где поток получает доступ к общему ресурсу, и предотвратить одновременное использование ресурса.
- Перед использованием ресурса поток входит в критический интервал (вызывает функцию EnterCriticalSection).
- Если после этого какой-либо другой поток попытается войти в тот же самый критический интервал, его выполнение приостановится, пока первый поток не покинет интервал с помощью вызова LeaveCriticalSection.
- Похоже на взаимоисключение, но используется только для потоков одного процесса.
- Существует также функция TryEnterCriticalSection, которая проверяет, занят ли критический интервал в данный момент.
- С ее помощью поток в процессе ожидания доступа к ресурсу может не блокироваться, а выполнять какие-то полезные действия.
Критические интервалы
//Для использования критического интервала, нужно объявить переменную типа CRITICAL_SECTION
CRITICAL_SECTION CS;
// Потом эту переменную CS нужно инициализировать (создать критический интервал)
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
InitializeCriticalSection(&CS);
}
// используем критический интервал в потоке, когда нужно блокировать доступ к данным
void __fastcall TMyThread::Execute()
{
FreeOnTerminate = true; // освободить занятую потоком память по окончании его работы
for(int i=0; i<10000; i++)
{
// -- какие-то сложные вычисления в цикле
if(Terminated) break; // прекратить извне поток
// блокировать доступ к данным (войти в критический интервал)
EnterCriticalSection(&Form1->CS);
... доступ к глобальным данным
// закрыть критический интервал (покинуть критический интервал)
LeaveCriticalSection(&Form1->CS);
}
}
// Когда критический интервал становиться не нужен, удаляем его
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
DeleteCriticalSection(&CS); // удалить критический интервал
}
Защищенный доступ к переменным
- Существует ряд функций, позволяющих работать с глобальными переменными из всех потоков не заботясь о синхронизации, т.к. эти функции сами за ней следят.
- Это функции:
- InterlockedIncrement
- InterlockedDecrement,
- InterlockedExchange,
- InterlockedExchangeAdd
- InterlockedCompareExchange
- Например, функция InterlockedIncrement увеличивает значение 32-битной переменной на единицу - удобно использовать для различных счетчиков.
TMultiReadExclusiveWriteSynchronizer
Методы
void BeginRead();
void EndRead();
bool BeginWrite();
void EndWrite();
TMultiReadExclusiveWriteSynchronizer
Нить 1
while(!Sync->BeginWrite()){
Sleep(1000);
Sync->EndWrite();
}
…
// обработка общего ресурса
…
Sync->EndWrite();
Нить 2
Sync->BeginRead();
…
// обработка общего ресурса
…
Sync->EndRead();
TCriticalSection
Методы
void Enter();
void Acquire();
void Leave();
void Release();
TCriticalSection
Нить 1
sect->Enter();
…
// обработка общего ресурса
…
sect->Leave();
TEvent
Методы
void ResetEvent()
void SetEvent()
TWaitResult WaitFor(int Timeout)
enum TWaitResult {
wrSignaled,
wrTimeout,
wrAbandoned,
wrError
};
TEvent
Нить 1
TWaitResult w;
w = Event->WaitFor(1000);
if(w == wrSignaled)
// дождались сигнала
else
// не дождались
Вопросы к экзамену
- Параллельная обработка. Основные понятия. Средства обеспечения работы процессов.
- Параллельная обработка. Средства реализации взаимных исключений и синхронизации нитей процессов.
- Программное решение проблемы взаимного исключения
- Двоичные семафоры
- Простые критические интервалы
- Мониторы
- Параллельная обработка. Механизмы передачи сообщений между процессами.
- Средства синхронизации процессов в Windows
- Объекты API
- Классы VCL Borland C++ Builder
Декларативное программирование
История развития языков программирования
- 40гг. – первые цифровые компьютеры – программирование путем коммутации проводов.
- программирование на машинном языке
- появление ассемблеров – машинные команды получают мнемонические имена (LOAD, STORE, ADD, …)
- конец 50х – создание первого компилятора для языка FORTRAN (FORmula TRANslator – транслятор формул)
- более удобное средство для написания формул, чем ассемблер
- переносимость кода
История развития языков программирования
- Архитектура языков программирования должна быть максимально приближена к архитектуре компьютеров для наиболее эффективного использования его ресурсов.
- Компьютер состоит из процессора и памяти – значит программа должна состоять из последовательности инструкций, выполняемых процессором и модифицирующих память.
Парадигма языка программирования
- Компьютер представляется в виде туповатого исполнителя, тем не менее поддающегося обучению.
- Исполнитель может исполнять некоторые простейшие команды.
- Обучение происходит путем формирования процедур из команд и использования их в дальнейшем вместо повторения последовательности команд.
- Программа описывает процесс последовательного, пошагового решения задачи.
Наклонения предложений в грамматике
- изъявительное (повествовательные)
- вопросительное
- повелительное (императивное)
- Изученные языки С/C++ относятся к императивным языкам.
- Другие названия – директивные, процедурные.
Программирование в повествовательном наклонении
- Стиль программирования, в котором программа представляется в как совокупность утверждений получил название декларативный.
- Программа на императивном языке программирования предписывает, как достичь требуемую цель; декларативная программа заявляет (декларирует), что должно быть достигнуто в качестве цели.
- Наиболее важные разновидности
- функциональное программирование
- логическое (реляционное) программирование
Особенности декларативного программирования
- Особое внимание уделяется тому, что нужно сделать, а не тому как этого достичь.
- Описание вычислений производится используя уравнения, функции, логические выводы и т. п
Не используют понятия состояния и не содержат переменных, отсюда:
- не могут использовать операторы присваивания, так как нечему присваивать;
- понятие последовательности выполнения команд становится бессмысленным и, значит, бесполезными становятся операторы управления процессом вычислений.
Предположим, требуется пройти в городе из пункта А в пункт Б.
- Декларативная программа - это план города, в котором указаны оба пункта, плюс правила уличного движения. Руководствуясь этими правилами и планом города, курьер сам найдет путь от пункта А к пункту Б.
- Императивная программа - это список команд примерно такого рода: от пункта А по ул. Садовой на север до площади Славы, оттуда по ул. Пушкина два квартала, потом повернуть направо и идти до Театрального переулка, по этому переулку налево по правой стороне до дома 20, который и есть пункт Б.
Виды декларативного программирования
- Функциональное программирование основывается на математическом понятии функции, которая не изменяет свое окружение (в отличии от функций в процедурных языках, допускающих побочные эффекты)
- Логическое программирование - программы выражены в виде формул математической логики и компьютер для решения задачи пытается вывести логические следствия из них.
Достоинства декларативных языков
- В основе декларативных языков лежит не какая-то машинная модель, а логика и математика.
Появляется возможность формализовать знания о проблеме непосредственно в терминах языка программирования.
- Необходимость иметь дело только (или главным образом) с логическим компонентом значительно упрощает программирование.
- Декларативные языки хорошо подходят для программирования параллельных компьютеров.
- Пригодность для формальных рассуждений.
Недостатки декларативных языков
- Существующие формы декларативного программирования плохо справляются с временными аспектами многих задач.
- Отсутствует возможность адекватно выразить в программе естественный параллелизм задачи.
- Низкая эффективность.
Логическое программирование
- Основано на логике предикатов.
- Основное внимание уделяется описанию структуры прикладной задачи, а не выработке предписаний компьютеру, что ему следует делать.
- Наиболее известный язык логического программирования PROLOG (от французского PROgrammation LOGique)
- Пролог часто называют языком искусственного интеллекта - с его помощью решаются задачи создания экспертных систем и систем обработки естественных языков.
Пролог
- Как и для других декларативных языков, при работе с Прологом мы описываем ситуацию (правила и факты) и формулируем цель (запрос), позволяя интерпретатору Пролога найти решение задачи за нас.
- Под интерпретатором Пролога мы будем понимать механизм решения задачи при помощи языка Пролог. Другими словами, интерпретатор языка Пролог - это исполнитель Пролог-программ, т. е. та "активная сила", которая выполняет программы, написанные на Прологе.
Круг задач Пролог
- задачи, связанные с разработкой систем искусственного интеллекта (различные экспертные системы, программы-переводчики, интеллектуальные игры).
- обработка естественного языка
- обладает мощными средствами, позволяющими извлекать информацию из баз данных
- решении задач составления сложных расписаний
- не является универсальным языком программирования и не предназначен, например, для решения задач, связанных с графикой или численными методами
Программа на языке Пролог