ГлавнаяarrowСистемное программированиеarrow30. Взаимодействие асинхронных процессов. Параллельная работа процессов в реальном времени

30. Взаимодействие асинхронных процессов. Параллельная работа процессов в реальном времени

В вычислительной системе может быть создана иерархическая структура запущенных на выполнение процессов. Один процесс может породить другой процесс, и в этом случае первый процесс называется РОДИТЕЛЬСКИМ, а второй процесс - ДОЧЕРНИМ. При запуске какой-либо программы из командного процессора (например, COMMAND.COM, Нортон коммандер или ДОС Навигатор), он выступает в роли родительского процесса. Дочерний процесс, в свою очередь, может запустить несколько дочерних процессов и так далее, таким образом создается иерархия процессов.
Говорят, что система работает в РЕАЛЬНОМ ВРЕМЕНИ, если время ее реакции на внешние события сопоставима с периодичностью их наступления. Например, система управления технологическим процессом должна оперативно получать информацию от многочисленных датчиков и обеспечивать минимальную задержку выдачи управляющих воздействий на исполнительные механизмы.
В многозадачных операционных системах все запущенные процессы работают параллельно и могут обмениваться информацией в реальном или близком к реальному времени. В однозадачной операционной системе MS-DOS родительский и дочерний процессы работать параллельно не могут, и обычно родительский процесс может продолжить свою работу только после завершения дочернего процесса.
В настоящей лабораторной работе мы предпримем меры для того, чтобы заставить наши родительский и дочерний процессы работать параллельно и обмениваться информацией. Для этого мы выделим часть кода первого процесса, назовем его ФУНКЦИЕЙ ОБРАБОТКИ ВНЕШНЕГО СОБЫТИЯ (АППАРАТНОГО ПРЕРЫВАНИЯ) и заставим Центральный Процессор вызывать нашу функцию каждый раз при наступлении этого внешнего события.
При этом основным работающим процессом является дочерний процесс, а от родительского реально работающей остается только функция обработки внешнего события. При возникновении события вырабатывается сигнал аппаратного прерывания, дочерний процесс временно приостанавливается, происходит сохранение в стеке его контекста (содержимого регистров процессора), и управление передается функции обработки прерывания родительского процесса. По окончании ее работы восстанавливается из стека контекст дочернего процесса, и он продолжает свою работу с прерванного места, ничего не подозревая о том, что его кто-то только что прерывал.
В настоящей работе мы будем обрабатывать два типа внешних событий - ПРЕРЫВАНИЕ ОТ ТАЙМЕРА и ПРЕРЫВАНИЕ ОТ КЛАВИАТУРЫ, причем их обработка будет простейшей и заключаться в подсчете количества этих событий. Каждому типу внешнего события соответствует начальный адрес программы - обработчика этого события (вектор прерывания), который хранится в фиксированных ячейках оперативной памяти - таблицы векторов прерываний. В операционной системе MS-DOS каждый вектор прерывания является дальним (far) указателем на функцию обработки прерывания, то есть состоит из сегмента и смещения. До запуска нашего родительского процесса эти векторы указывают на программы-обработчики, принадлежащие Операционной системе. Для подсчета количества указанных событий нам необходимо дополнить соответствующую программу-обработчик собственным кодом. Для этого нужно подменить вектор прерывания на адрес нашей собственной программы-обработчика, которая производит подсчет, и уже из нашей программы вызвать подмененный обработчик Операционной системы.
Прерывания от ТАЙМЕРА вырабатываются каждый раз по истечении некоторого интервала времени, в нашем случае приблизительно один раз в 55 миллисекунд. Прерывания от КЛАВИАТУРЫ вырабатываются как при нажатии, так и при отпускании клавиш, а количество прерываний зависит от типа клавиши - символьной или функциональной.
Для передачи данных между процессами мы будем использовать ОБЩЕЕ ПОЛЕ ПАМЯТИ, в котором находятся РАЗДЕЛЯЕМЫЕ ДАННЫЕ. Как правило, это поле памяти выделяется в адресном пространстве родительского процесса, а дочернему процессу передается только УКАЗАТЕЛЬ НА НАЧАЛО (адрес первой ячейки) этого поля памяти. Таким образом, первый процесс может передать второму процессу достаточно большой объем данных. Из большого количества способов передачи этого адреса (придумайте несколько способов самостоятельно) мы применим способ передачи адреса через аргументы (дополнительные текстовые параметры) командной строки запуска дочернего процесса.
Увеличивая функцией обработки прерывания текущее значение разделяемой переменной - счетчика внешних событий, мы сможем из первого (родительского) процесса моментально, то есть в реальном времени, передавать информацию о наступлении события во второй (дочерний) процесс.
Для того, чтобы грамотно перехватить аппаратное прерывание (то есть: вставить в имеющуюся программу-обработчик прерывания собственный код), необходимо выполнить следующую последовательность действий:
1) Сохранить адрес (вектор) СТАРОГО обработчика прерывания при помощи функции языка СИ getvect( ).
2) Поместить на его место в таблице векторов новый адрес ВАШЕГО обработчика при помощи функции языка СИ setvect( ).
3) При выходе из программы ВОССТАНОВИТЬ адрес старого обработчика в таблице векторов функцией setvect( ).
 

Hosted by uCoz