
- •Введение
- •1. Лабораторная работа № 1
- •1.1. Цель работы
- •1.2. Теоретическое введение
- •1.2.1. Получение информации об операционной системе
- •1.2.2. Получение информации из реестра
- •1.2.3. Получение информации о системных каталогах Windows
- •1.2.4. Получение информации о диске
- •1.3. Создание приложения для получения характеристик компьютера и операционной системы
- •Контрольные вопросы
- •2. Лабораторная работа №2
- •2.1.Цель работы
- •2.2. Теоретическое введение
- •2.2.1. Процедуры и функции для работы с виртуальной памятью
- •2.3. Создание приложения, работающего с виртуальной памятью
- •2.4. Задание для самостоятельной работы
- •Контрольные вопросы
- •3. Лабораторная работа № 3
- •3.1. Цель работы
- •3.2. Пример использования механизма выделения виртуальной памяти для решения конкретных задач
- •3.3. Задания для самостоятельной работы
- •Контрольные вопросы
- •4. Лабораторная работа № 4
- •4.1. Цель работы
- •4. 2. Теоретическое введение
- •4.2.1 Создание или открытие объекта ядра «файла»
- •4.2.2 Создание объекта ядра «файл, проецируемый в память»
- •4.2.3 Проецирование файловых данных на адресное пространство процесса
- •4.2.4 Отмена проецирования на адресное пространство процесса объекта ядра «файл, проецируемый в память»
- •4.2.5 Закрытие объектов ядра «файл, проецируемый в память» и «файл»
- •4.3 Примеры программ, выполняющих проецирование в память
- •4.3.1 Пример 1
- •4.3.2 Пример 2
- •4.4. Задания для самостоятельной работы
- •Контрольные вопросы
- •5. Лабораторная работа № 5
- •5.1.Цель работы
- •5.2. Теоретическое введение
- •5.2.1. Создание процесса
- •5.2.2. Запуск внешней программы функцией WinExec
- •5.2.3. Запуск внешней программы и открытие документа функцией ShellExecute
- •При успешном выполнении функция ShellExecute возвращает целое значение, большее 32. Значение меньшее или равное 32 указывает на ошибку. Значения эти те же, что и для функции WinExec.
- •5.2.4. Создание потока
- •5.2.5. Завершение процесса
- •5.2.6. Завершение потока
- •5.2.7. Изменение класса приоритета процесса
- •5.2.8. Получение информации о классе приоритета процесса
- •5.2.9. Изменение уровня приоритета потока
- •5.2.10. Получение информации о приоритете потока
- •5.3. Примеры программ для работы с процессами и потоками
- •5.3.1. Создание процесса с помощью функции CreateProcess.
- •5.3.2. Создание процесса с помощью функции WinExec.
- •5.3.3. Создание процесса с помощью функции ShellExecute.
- •5.3.4. Создание многопоточного приложения.
- •5.4. Задания для самостоятельной работы
- •Контрольные вопросы
- •6. Лабораторная работа № 6
- •6.1. Цель работы
- •6.2. Теоретическое введение
- •6.2.1. Получение «мгновенного снимка» системы
- •6.2.2. Получение информации о процессах
- •6.2.3. Получение информации о потоках
- •6.2.4. Получение информации о модулях
- •6.2.5. Информация о кучах (heap)
- •6.2.6. Информация о виртуальной памяти.
- •6.2.7. Алгоритм работы функций ToolHelp
- •6.2.8. Как получить карту памяти любого процесса
- •6.3. Пример использования функций ToolHelp
- •6.4. Задания для самостоятельной работы
- •Контрольные вопросы
- •7. Лабораторная работа № 7
- •7.1. Цель работы
- •7.2. Теоретическое введение
- •7.2.1. Критические секции
- •7.2.2. Синхронизация с использованием объектов ядра
- •7.2.3. Wait-функции
- •7.2.4. Синхронизация с использованием процессов и потоков
- •7.2.5. Объекты Mutex
- •7.2.6. Семафоры
- •7.2.7. События
- •7.3 Примеры работы с объектами синхронизации
- •7.3.1 Пример 1
- •7.3.1 Пример 2
- •7.4. Задания для самостоятельной работы
- •Контрольные вопросы
- •8. Лабораторная работа № 8
- •8.1. Цель работы
- •8.2 Теоретическое введение
- •8.2.1 Создание dll
- •8.2.2 Неявная загрузка dll
- •8.2.3 Явная загрузка dll
- •8.2.4 Внедрение dll в адресное пространство другого процесса
- •8.3 Пример работы с dll
- •8.3.1 Создание dll, которая выполняет перехват нажатых клавиш
- •8.3.2 Разработка приложения, которое выполняет анализ и обработку нажатых клавиш.
- •8.4 Индивидуальные задания
- •Контрольные вопросы
- •9.2.2. Функции для работы с объектом «уведомление об изменении файловой системы»
- •9.3. Пример работы системы уведомления об изменениях в файловой системе
- •9.4. Задания для самостоятельной работы
- •Контрольные вопросы
- •Литература
- •214013 Г. Смоленск, Энергетический проезд, 1
7.3 Примеры работы с объектами синхронизации
7.3.1 Пример 1
Пример 1 (см. рисунок 7.1) демонстрирует работу таких объектов синхронизации, как критические секции, объекты mutex и события. В приложении также рассматривается работа функции WaitForMultipleObjects в режиме ожидания освобождения всех объектов и в режиме ожидания освобождения какого-либо одного объекта.
На форму переносятся командные кнопки Button1-Button6 и компонент Memo1.
Для программирования приложения выполняются следующие действия:
Определение глобальных переменных. Для этого в область VAR (после определения объекта Форма) добавляются следующие строки:
var
Form1: TForm1;
Sum:Integer; {Переменная, в которую записывается результат вычислений }
f:TextFile; {файловая переменная}
cs:TRTLCriticalSection; {критическая секция}
mt:THANDLE; {Дескриптор объекта mutex}
ev:THANDLE; {Дескриптор объекта «событие»}
Пример работы критических секций. Работа критических секций рассматривается на следующем примере – создается два дополнительных потока. Первый поток занимает критическую секцию, увеличивает число на 1 и освобождает критическую секцию. Второй поток записывает очередное число, сформированное первым потоком в файл. Программирование кнопки «Критические секции».
Включите в текст приложения дополнительную функцию Thread1, которая выполняет вычисления (увеличивает число на 1):
procedure Thread1;
begin
While Sum<20 do
begin
EnterCriticalSection(cs);
Inc(Sum);
Sleep(30);
LeaveCriticalsection(cs);
end;
end;
Включите в текст приложения дополнительную функцию Thread2, которая записывает в файл результат вычислений функции Thread1:
procedure Thread2;
begin
While Sum <20 do
begin
EnterCriticalSection(cs);
Writeln(f,IntToStr(Sum));
Sleep(30);
LeaveCriticalsection(cs);
end;
end;
Для события OnClick кнопки «Критически секции» напишите следующий программный код:
procedure TForm1.Button1Click(Sender: TObject);
VAR hThread1,hThread2:THandle;
pFunc1,pFunc2:pointer;
ThreadID1,ThreadID2:CARDINAL;
begin
Sum:=0;
AssignFile(f,'C:\tempCS.txt');
Rewrite(f);
InitializeCriticalSection(cs);
pFunc1:=@Thread1;
pFunc2:=@Thread2;
hThread1:=CreateThread(nil,0,pFunc1,nil,0,ThreadID1);
hThread2:=CreateThread(nil,0,pFunc2,nil,0,ThreadID2);
While Sum<20 do
begin
EnterCriticalSection(cs);
Sleep(30);
LeaveCriticalSection(cs);
end;
ShowMessage ('Работа завершена');
CloseFile(f);
end;
Пример работы с объектом mutex. Работа объекта mutex рассматривается на примере аналогичном рассмотренному в п.2 (работа с критическими секциями). Создается два дополнительных потока. Первый поток занимает объект mutex, увеличивает число на 1, выводит его значение в поле Memo1 и освобождает объект mutex. Второй поток записывает очередное число, сформированное первым потоком в файл. Программирование кнопки «Mutex»:
Включите в текст приложения дополнительную функцию Thread3, которая выполняет вычисления (увеличивает число на 1):
procedure Thread3;
begin
While Sum<20 do
begin
WaitForSingleObject(mt,INFINITE);
Inc(Sum);
Form1.Memo1.Lines.Add(IntToStr(sum));
Form1.Refresh;
ReleaseMutex(mt);
Sleep(20);
end;
end;
Включите в текст приложения дополнительную функцию Thread4, которая записывает в файл результат вычислений функции Thread3:
procedure Thread4;
begin
While Sum <20 do
begin
WaitForSingleObject(mt,INFINITE);
Writeln(f,IntToStr(Sum));
ReleaseMutex(mt);
Sleep(20);
end;
CloseFile(f);
end;
Для события OnClick кнопки «Mutex» напишите следующий программный код:
procedure TForm1.Button2Click(Sender: TObject);
VAR hThread3,hThread4:THandle;
pFunc3,pFunc4:pointer;
ThreadID3,ThreadID4:CARDINAL;
begin
Sum:=0;
Memo1.Clear;
// Form1.Refresh;
AssignFile(f,'C:\tempMT.txt');
Rewrite(f);
mt:=CreateMutex(nil,FALSE,PChar(''));
pFunc3:=@Thread3;
pFunc4:=@Thread4;
hThread3:=CreateThread(nil,0,pFunc3,nil,0,ThreadID3);
hThread4:=CreateThread(nil,0,pFunc4,nil,0,ThreadID4);
end;
Пример работы с объектом «событие с автосбросом». Работа объекта «событие» рассматривается на примере аналогичном рассмотренному в пп. 2 и 3. Создается два дополнительных потока. Первый поток занимает объект «событие», увеличивает число на 1, выводит его значение в поле Memo1 и освобождает объект «событие». Второй поток записывает очередное число, сформированное первым потоком в файл. Программирование кнопки «События»:
Включите в текст приложения дополнительную функцию Thread5, которая выполняет вычисления (увеличивает число на 1):
procedure Thread5;
begin
While Sum<20 do
begin
WaitForSingleObject(ev,INFINITE);
Inc(Sum);
Form1.Memo1.Lines.Add(IntToStr(sum));
Form1.Refresh;
SetEvent(ev);
Sleep(20);
end;
end;
Включите в текст приложения дополнительную функцию Thread6, которая записывает в файл результат вычислений функции Thread5:
procedure Thread6;
begin
While Sum <20 do
begin
WaitForSingleObject(mt,INFINITE);
Writeln(f,IntToStr(Sum));
SetEvent(ev);
Sleep(20);
end;
CloseFile(f);
end;
Для события OnClick кнопки «События» напишите следующий программный код:
procedure TForm1.Button3Click(Sender: TObject);
VAR hThread5,hThread6:THandle;
pFunc5,pFunc6:pointer;
ThreadID5,ThreadID6:CARDINAL;
begin
Sum:=0;
Memo1.Clear;
Form1.Refresh;
AssignFile(f,'C:\tempEV.txt');
Rewrite(f);
ev:=CreateEvent(nil,FALSE,TRUE,PChar(''));
pFunc5:=@Thread5;
pFunc6:=@Thread6;
hThread5:=CreateThread(nil,0,pFunc5,nil,0,ThreadID5);
hThread6:=CreateThread(nil,0,pFunc6,nil,0,ThreadID6);
end;
Пример работы функции WaitForMultipleObjects, которая ожидает завершения всех запущенных процессов. В примере запускается три процесса «Калькулятор» и приложение ожидает завершения всех трех процессов, после чего работа приложения может быть продолжена. Для события OnClick кнопки «Ожидание завершения всех процессов» напишите следующий программный код:
procedure TForm1.Button5Click(Sender: TObject);
VAR StartInfo:TStartUpInfo;
ProcInfo:TProcessInformation;
h:PWOHandleArray;
i:Integer;
err:Boolean;
begin
err:=False;
For i:=0 to 2 do
begin
//Очистка полей структуры StartInfo
FillChar(StartInfo,Sizeof(StartInfo),#0);
StartInfo.cb:=Sizeof(StartInfo);
If not CreateProcess(nil,'C:\WINNT\system32\calc.exe',nil,nil,False,
NORMAL_PRIORITY_CLASS,nil,nil,StartInfo,ProcInfo)
then
begin
ShowMessage('Ошибка '+IntToStr(GetLastError));
err:=True;
end
else
begin
h[i]:=ProcInfo.hProcess;
end;
end;
If not err
then WaitFormultipleObjects(3,h,True,INFINITE);
end;
Пример работы функции WaitForMultipleObjects, которая ожидает завершения одного из запущенных процессов. В примере запускается три процесса «Калькулятор» и приложение ожидает завершения какого-либо одного процесса, после чего работа приложения может быть продолжена. Для события OnClick кнопки «Ожидание завершения одного из процессов» напишите следующий программный код:
procedure TForm1.Button6Click(Sender: TObject);
VAR StartInfo:TStartUpInfo;
ProcInfo:TProcessInformation;
h:PWOHandleArray;
i:Integer;
err:Boolean;
begin
err:=False;
For i:=0 to 2 do
begin
//Очистка полей структуры StartInfo
FillChar(StartInfo,Sizeof(StartInfo),#0);
StartInfo.cb:=Sizeof(StartInfo);
If not CreateProcess(nil,'C:\WINNT\system32\calc.exe',nil,nil,False,
NORMAL_PRIORITY_CLASS,nil,nil,StartInfo,ProcInfo)
then
begin
ShowMessage('Ошибка '+IntToStr(GetLastError));
err:=True;
end
else
begin
h[i]:=ProcInfo.hProcess;
end;
end;
If not err
then
WaitFormultipleObjects(3,h,False,INFINITE);
end;
Завершение работы приложения. Для события OnClick кнопки «Выход» напишите следующий программный код:
procedure TForm1.Button4Click(Sender: TObject);
begin
Form1.Close;
end;