Министерство образования и науки
Российской Федерации
НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
№ ____
СИСТЕМНОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ
Методические указания к лабораторным работам
для студентов IV курса АВТФ
(специальность 210100)
дневной формы обучения
НОВОСИБИРСК
2004
Составитель: А.В. Гунько, канд. техн. наук, доц.
Работа подготовлена на кафедре автоматики
© Новосибирский государственный технический университет, 2004 г.
ЛАБОРАТОРНАЯ РАБОТА № 1
ПРОГРАММИРОВАНИЕ В WINDOWS
1. Цель работы: Изучить способы и средства написания параллельно выполняющихся процессов и потоков средствами языка C++ в операционных системах семейства Windows.
2. Краткие теоретические сведения.
Применяемые функции WinAPI, их параметры.
CreateProcess – создание процесса:
BOOL CreateProcess
(LPCTSTR lpApplicationName, // имя исполняемого модуля
LPTSTR lpCommandLine, // Командная строка
LPSECURITY_ATTRIBUTES lpProcessAttributes,
// Указатель на структуру SECURITY_ATTRIBUTES
LPSECURITY_ATTRIBUTES lpThreadAttributes,
// Указатель на структуру SECURITY_ATTRIBUTES
BOOL bInheritHandles, // Флаг наследования текущего процесса
DWORD dwCreationFlags, // Флаги способов создания процесса
LPVOID lpEnvironment, // Указатель на блок среды
LPCTSTR lpCurrentDirectory, // Текущий диск или каталог
LPSTARTUPINFO lpStartupInfo,// Указатель нас структуру STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation
// Указатель нас структуру PROCESS_INFORMATION
);
pApplicationName. Указатель на строку которая заканчивается нулем и содержит имя выполняемого модуля. Этот параметр может быть NULL - тогда имя модуля должно быть в lpCommandLine самым первым элементом. Если операционная система NT и модуль 16 разрядов - параметр NULL стоит обязательно. Имя модуля может быть абсолютным или относительным. Если относительное, то будет использована информация из lpCurrentDirectory или текущий каталог.
lpCommandLine. Командная строка. Здесь передаются параметры. Она может быть NULL. Здесь можно указать и путь и имя модуля.
lpProcessAttributes.Здесь определяются атрибуты защиты для нового приложения. Если указать NULL то система сделает это по умолчанию.
lpThreadAttributes. Здесь определяются атрибуты защиты для первого потока созданного приложением. NULL опять приводит к установке по умолчанию.
bInheritHandles. Флаг наследования от процесса, производящего запуск. Здесь наследуются дескрипторы. Унаследованные дескрипторы имеют те же значения и права доступа, что и оригиналы.
dwCreationFlags. Флаг способа создание процесса и его приоритет:
CREATE_DEFAULT_ERROR_MODE - новый процесс не наследует режим ошибок (error mode) вызывающего процесса.
CREATE_NEW_CONSOLE - новый процесс получает новую консоль вместо того, чтобы унаследовать родительскую.
CREATE_NEW_PROCESS_GROUP - создаваемый процесс - корневой процесс новой группы.
CREATE_SEPARATE_WOW_VDM - (только Windows NT): Если этот флаг установлен, новый процесс запускается в собственной Virtual DOS Machine (VDM).
CREATE_SHARED_WOW_VDM - (только Windows NT): Этот флаг указывает функции CreateProcess - запустить новый процесс в разделяемой Virtual DOS Machine.
CREATE_SUSPENDED - первичная нить процесса создается в спящем (suspended) состоянии и не выполняется до вызова функции ResumeThread.
CREATE_UNICODE_ENVIRONMENT - если этот флаг установлен, блок переменных окружения, указанный в параметре lpEnvironment, использует кодировку Unicode. Иначе - кодировку ANSI.
DEBUG_PROCESS - если этот флаг установлен, вызывающий процесс считается отладчиком, а новый процесс - отлаживаемым.
DEBUG_ONLY_THIS_PROCESS - если этот флаг не установлен и вызывающий процесс находится под отладкой, новый процесс так же становится отлаживаемым тем же отладчиком.
DETACHED_PROCESS - создаваемый процесс не имеет доступа к родительской консоли.
Этот флаг нельзя использовать с флагом CREATE_NEW_CONSOLE.
HIGH_PRIORITY_CLASS - указывает на то, что процесс выполняет критичные по времени задачи
IDLE_PRIORITY_CLASS - указывает процесс, выполняются только когда система находится в состоянии ожидания
NORMAL_PRIORITY_CLASS - указывает на процесс, без каких либо специальных требований к выполнению.
REALTIME_PRIORITY_CLASS - указывает процесс имеющий наивысший возможный приоритет.
lpEnvironment. Указывает на блок среды. Если NULL, то будет использован блок среды родительского процесса. Блок среды это список переменных имя=значение в виде строк с нулевым окончанием.
lpCurrentDirectory.Указывает текущий диск и каталог. Если NULL то будет использован диск и каталог процесса родителя.
LpStartupInfo. Используется для настройки свойств процесса, например расположения окон и заголовок. Структура должна быть правильно инициализирована
STARTUPINFO sti;// структура
ZeroMemory(&sti,sizeof(STARTUPINFO));// обнулить
sti.cb=sizeof(STARTUPINFO);// указать размер
lpProcessInformation Структура PROCESS_INFORMATION с информацией о процессе. Будет заполнена Windows.
В результате выполнение функций вернет FALSE или TRUE. В случае успеха TRUE. Пример использования.
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
void main()
{
STARTUPINFO cif;
ZeroMemory(&cif,sizeof(STARTUPINFO));
PROCESS_INFORMATION pi;
if (CreateProcess("c:\windows\notepad.exe",NULL,
NULL,NULL,FALSE,NULL,NULL,NULL,&cif,pi)==TRUE)
{
cout << "process" << endl;
cout << "handle " << pi.hProcess << endl;
Sleep(1000);// подождать
TerminateProcess(pi.hProcess,NO_ERROR);// убрать процесс
}
}
CreateThread – создание потока:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
lpSecurityAttributes - обычно устанавливается в нуль, чтобы использовать заданные по умолчанию атрибуты защиты.
dwStackSize - размер стека. Каждый поток имеет собственный стек.
lpStartAddress - адрес памяти, где стартует поток. Он должен быть равен адресу функции в стандартном модуле, полученном при использовании оператора AddressOf.
lpParameter - long 32 разрядный параметр, который передается функции, запускающей новый поток.
dwCreationFlags - 32 бит переменная флагов, которая позволяет Вам управлять запуском потока (активный, приостановленный и т.д.). Подробнее об этих флагах можно почитать в Microsoft's online 32 bit reference.
lpThreadId - переменная, в которую загружается уникальный идентификатором нового потока.
Для упорядоченного вывода результатов работы процессов (потоков) на экран можно использовать функцию Sleep():
VOID Sleep(
DWORD dwMilliseconds // время ожидания в милисекундах
);
Поток вызывает функцию Sleep для того, чтобы добровольно отложить свое выполнение. Функция Sleep не осуществляет возврата до тех пор, пока не истечет указанное время. В течение него выполнение потока приостанавливается, и выделения для него процессорного времени не происходит.
Если параметр функции Sleep задан равным нулю, то поток будет лишен остатка выделенного ему кванта процессорного времени.
Когда поток вызывает функцию Sleep, задержка на заданное время относится к этому потоку. Система продолжает выполнять другие потоки этого и других процессов.
3. Методические указания.
Проект может быть реализован на Visual C++ 6.0 или в среде Borland C++ 5.0. В первом случае выбирается консольное приложение Win32 без дополнительных библиотек. Во втором случае в программу необходимо добавить файл включения windows.h.
Для обмена информацией между процессами рекомендуется использовать файлы. При использовании потоков для обмена информацией целесообразно использовать глобальные переменные.
4. Порядок выполнения работы.
4.1. Написать и отладить программу, реализующую порожденный процесс.
4.2. Написать и отладить программу, реализующую родительский процесс, вызывающий и отслеживающий состояние порожденных процессов (ждущий их завершения или уничтожающий их, в зависимости от варианта).
4.3. Написать и отладить программу, реализующую родительский процесс, вызывающий и отслеживающий состояние порожденных потоков (ждущий их завершения или уничтожающий их, в зависимости от варианта).
5. Варианты заданий.
5.1. Поиск всех простых чисел в указанном интервале чисел, разделенном на несколько диапазонов:
5.1.1. разработать программу, вычисляющую все простые числа в произвольном интервале;
5.1.2. написать программу, разбивающую заданный интервал на несколько диапазонов и проводящую поиск в каждом диапазоне в отдельном процессе. Запуск написанной ранее программы осуществлять функцией CreateProcess().
5.1.3. разработать программу, в которой поиск простых чисел производился бы отдельной функцией, а в главной функции заданный интервал разбивался на диапазоны, и для каждого диапазона в отдельном потоке вызывалась функция поиска.
5.2. Поиск указанной строки в указанном файле:
5.2.1. написать программу, которая производит поиск заданного сочетания символов в одной строке текстового файла;
5.2.2. разработать программу, которая обеспечивала бы поиск сочетания символов во всем файле. Но для обработки каждой строки следует вызывать написанную ранее программу, передавая ее в качестве параметра командной строки в функцию CreateProcess();
5.2.3. написанную программу поиска сочетания символов в одной строке представить в виде функции, которую следует вызывать из главной подпрограммы посредством функции CreateThread().