Программная реализация многозадачности
Когда пользователь запускает программу, Windows создает в памяти компьютера экземпляр программы, называемый процессом. Процесс не является точной копией *.ехе – файла, как это было, например в операционной системе ДОС. Процесс содержит в себе копию *.ехе – файла, а также некоторую другую информацию о функционировании данного приложения. В этой дополнительной информации хранятся, например, границы выделенной приложению памяти, что помогает аппаратно отслеживать корректности обращения к оперативной памяти со стороны приложения. Так как Windows поддерживает механизм виртуальной памяти, то среди этой информации находятся сведения о расположении сегментов программы. Здесь же содержится командная строка, формируемая при запуске программы.
Запустить процесс можно как при помощи командной строки системного меню Windows , при помощи программы Проводника, так и программно, из другого приложения. Это можно выполнить при помощи функций API :
Для 16-битных приложений используется функция WinExec :
UINT WinExec(
LPCSTR lpCmdLine , // command line
UINT uCmdShow // window style
);
Первый параметр является командной строкой, в которой указывается имя файла и параметры, указываемые после имени загружаемого файла.
После запуска, программа начинает параллельную работу относительно приложения-родителя и ее выполнение не зависит от других приложений, если, конечно, зависимость не предусмотрена самой природой приложений.
В среде Windows 32 следует использовать другой способ порождения процессов:
BOOL CreateProcess(
LPCTSTR lpApplicationName, // pointer to name of executable module
LPTSTR lpCommandLine, // pointer to command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security attributes
LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes
– 75 –
BOOL bInheritHandles, // handle inheritance flag
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // pointer to new environment block
LPCTSTR lpCurrentDirectory, // pointer to current directory name
LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO
LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION
);
Первый параметр является указателем на имя запускаемого файла. Имя может содержать полный путь к файлу (диск:\каталог\…\файл). Если имя не содержит пути, то операционная система ищет файл в текущем каталоге, затем в системных каталогах и в каталогах, указанных в разделе PATH при загрузке системы.
Второй параметр указывает на командную строку.
Третий и четвертый параметры определяют, может ли возвращаемый указатель процесса наследоваться дочерними процессами и потоками.
bInheritHandles и dwCreationFlags содержит дополнительные флаги управления созданием и приоритетом процесса.
lpEnvironment содержит указатель на буфер памяти, в котором будет создаваться служебная информация по процессу. Если равен NULL , то операционная система сама отводит место в памяти под эту информацию.
lpCurrentDirectory указатель на строку, содержащую путь к каталогу, который будет использоваться запускаемым процессом как текущий. Если значение поля равно , то текущей директорией будет считаться каталог, являющийся текущим для процесса-родителя.
lpStartupInfo определяет структуру STARTUPINFO , которая описывает окно, создаваемое для запускаемого процесса (в ней содержится информация, похожая на ту, которая передается в процедуру CreateWindow ).
lpProcessInformation указатель на структуру, заполняемую после создания нового процесса. Структура содержит информацию о созданном процессе.
Многопоточность в программе реализовать можно несколькими путями.
·Непосредственное использование системного таймера для указание процедуры, вызываемой периодически. Данный способ был рассмотрен в лекции "Использование Таймера". Это типичный представитель вытесняющей многозадачности. К достоинствам этого способа можно отнести то, что программа может устанавливать и изменять период вызова функции.
·Использование системного таймера для организации посылки синхронных сообщений выбранному окну (порядок организации описан в лекции "Использование Таймера"). С помощью данного способа реализуется невытесняющая многозадачность. Достоинство – изменяемая периодичность посылки сообщений. Недостаток – природа синхронных сообщений не гарантирует четкое выполнение периода прихода сообщений от таймера.
·Создание потоков. Данный способ подразумевает определение некоторой процедуры потока, которая запускается параллельно основному процессу приложения. Момент окончания выполнения потока контролирует сама поточная процедура.
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread1,¶ms,0,&iThread);
Первый параметр определяет атрибуты безопасности для запускаемого потока. Если он равен NULL , то данный поток не может использоваться дочерними процессами.
Второй параметр определяет начальный адрес потока (фактически - имя процедуры потока), например:
DWORD WINAPI Thread1(PVOID pvoid)
{
// Текст потока
}
Третий параметр является целым числом, которое передается создаваемому потоку как параметр ( PVOID pvoid ). В данном случае в качестве данного параметра выступает указатель на некоторую структуру данных. Таким образом, основной процесс имеет возможность передавать в поток необходимую информацию.
Четвертый параметр определяет дополнительные флаги создания потока. Если этот параметр равен нулю, то поток создастся немедленно.
Последний параметр является адресом переменной, в которую возвращается идентификатор потока.
Дата добавления: 2016-11-22; просмотров: 517;