Выполнение процессов в ходе программирования
Перечисление процессов, выполняемых в системе при программировании. Управление выполняемыми приложениями в рамках системы Windows. Свойства процессов в операционной системе. Описатель экземпляра процесса. Выполнение потоков при завершении процесса.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 05.12.2014 |
Размер файла | 143,7 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://allbest.ru
Введение
Microsoft Windows - сложная операционная система. Она включает в себя столько всего и делает так много, что одному человеку просто не под силу полностью разобраться в этой системе. Более того, из-за такой сложности и комплексности Windows трудно решить, с чего начать её изучение. Лично я всегда начинаю с самого низкого уровня, стремясь получить чёткое представление о базовых сервисах операционной системы. Разобравшись в основах, дальше двигаться проще. С этого момента я шаг за шагом, по мере необходимости, изучаю сервисы более высокого уровня, построенные именно на этом базисе.
СОМ -- это архитектура, где используются процессы, потоки, механизмы управления памятью, DLL, локальная память потоков, Unicode и многое другое. Если Вы знаеге, как устроены и работают эти фундаментальные сервисы операционной системы, то для освоения СОМ достаточно понять, как они применяются в этой архитектуре. Мне очень жаль тех, кто пытается перепрыгнуть через всё это и сразу же взяться за изучение архитектуры COM. Впереди у них долгий и тернистый путь; в их знаниях неизбежны пробелы, которые непременно будут мешать им в работе.
Рассматривая тот или иной сервис, я буду рассказывать, как им пользуется система и как им должно пользоваться приложение. Реализуя их в виде универсальных функций и классов C++ и комбинируя в них те или иные базовые сервисы Windows, Вы получите нечто большее суммы отдельных частей.
1.Перечисление процессов, выполняемых в системе
Многие разработчики программного обеспечения пытаются создавать инструментальные средства или утилиты для Windows, требующие перечисления процессов, выполняемых в системе Изначально в Windows API не было функций, которые позволяли бы это делать. Однако в Windows NT ведется постоянно обновляемая база данных Performance Data. В ней содержится чуть ли не тонна информации, доступ ной через функции реестра вроде RegQueryValueEx, для которой надо указать корневой раздел HKEY_PERFORMANCE_DATA. Мало кто из программистов знает об этой базе данных, и причины тому кроются, на мой взгляд, в следующем.
· Для нее не предусмотрено никаких специфических функций, нужно использовать обычные функции реестра.
· Ее нет в Windows 95 и Windows 98.
· Структура информации в этой базе данных очень сложна; многие просто из бегают ею пользоваться (и другим не советуют).
Чтобы упростить работу с этой базой данных, Microsoft создала набор функций под общим названием Performance Data Helper (содержащийся в PDH.dll). Если Вас интересует более подробная информация о библиотеке PDH.dll, ищите раздел по функциям Performance Data Helper в документации Platform SDK. Как я уже упоминал, в Windows 95 и Windows 98 такой базы данных нет. Вместо них предусмотрен набор функций, позволяющих перечислять процессы. Они включены в ToolHelp API За информацией о них я вновь отсылаю Вас к документации Platform SDK -- ищите разделы по функциям Process32First и Process32Next,
Но самое смешное, что разработчики Windows NT, которым ToolHelp-функции явно не нравятся, не включили их в Windows NT. Для перечисления процессов они создали свой набор функций под общим названием Process Status (содержащийся в PSAPI.dll). Так что ищите в документации Platform SDK раздел по функции Enum Processes.
Microsoft, которая до сих пор, похоже, старалась усложнить жизнь разработчи кам инструментальных средств и утилит, все же включила ToolHelp-функции в Win dows 2000. Наконец-то и эти разработчики смогут унифицировать свой код хотя бы для Windows 95, Windows 98 и Windows 2000!
Процессы
Эта глава о том, как система управляет выполняемыми приложениями. Сначала я определю понятие "процесс" и объясню, как система создает объект ядра "процесс" Затем я покажу, как управлять процессом, используя сопоставленный с ним объект ядра. Далее мы обсудим атрибуты (или свойства) процесса и поговорим о нескольких функциях, позволяющих обращаться к этим свойствам и изменять их. Я расскажу также о функциях, которые создают (порождают) в системе дополнительные процессы. Ну и, конечно, описание процессов было бы неполным, если бы я не рассмотрел механизм их завершения.
Процесс обычно определяют как экземпляр выполняемой программы, и он состоит из двух компонентов
· объекта ядра, через который операционная система управляет процессом. Там же хранится статистическая информация о процессе,
· адресного пространства, в котором содержится код и данные всех EXE- и DLL модулей Именно в нем находятся области памяти, динамически распределяе мой для стеков потоков и других нужд.
Рис. 4-1. Операционная система выделяет потокам кванты времени по принципу карусели
Процессы инертны. Чтобы процесс что-нибудь выполнил, в нем нужно создать поток. Именно потоки отвечаю за исполнение кода, содержащегося в адресном пространстве процесса В принципе, один процесс может владеть несколькими потоками, и тогда они "одновременно" исполняют код в адресном пространстве процесса.
Для этого каждый поток должен располагать собственным набором регистров процессора и собственным стеком. В каждом процессе есть минимум один поток. Если бы у процесса не было ни одного потока, ему нечего было бы делать на этом свете, и система автоматически уничтожила бы его вместе с выделенным ему адресным пространством.
Чтобы все эти потоки работали, операционная система отводит каждому из них определенное процессорное время. Выделяя потокам отрезки времени (называемые квантами) по принципу карусели, она создает тем самым иллюзию одновременного выполнения потоков Рис 4-1 иллюстрирует распределение процессорного времени между потоками па машине с одним процессором. Если в машине установлено более одного процессора, алгоритм работы операционной системы значительно усложняет ся (в этом случае система стремится сбалансировать нагрузку между процессорами).
При создании процесса первый (точнее, первичный) поток создается системой автоматически. Далее этот поток может породить другие потоки, те в свою очередь -- новые и т. д.
WINDOWS 2000 Windows 2000 в полной мере использует возможности машин с несколькими процессорами. Windows 2000 способна закрепить каждый поток за отдельным процессором, и тогда два потока исполняются действительно одновременно. Ядро Windows 2000 полностью поддерживает распределение процессорного времени между потоками и управление ими на таких системах. Вам не придется делать ничего особенного в своем коде, чтобы задействовать преимущества многопроцессорной машины.
WINDOWS 98 Windows 98 работает только с одним процессором. Даже если у компьютера несколько процессоров, под управлением Windows 98 действует лишь один из них -- остальные простаивают.
Ваше первое Windows-приложение
Windows поддерживает два типа приложений: основанные на графическом интерфейсе (graphical user interface, GUI) и консольные (console userinterface, CUI) V приложений первого типа внешний интерфейс чисто графический GUI-приложения создают окна, имеют меню, взаимодействуют с пользователем через диалоговые окна и вооб ще пользуются всей стандартной "Windows'oвской" начинкой. Почти все стандартные программы Windows -- Notepad, Calculator, Wordpad и др -- являются GUI-приложениями. Приложения консольного типа работают в текстовом режиме: они не формируют окна, не обрабатывают сообщения и не требуют GUI. И хотя консольные приложения на экране тоже размещаются в окне, в нем содержится только текст. Командные процессоры вроде Cmd.exe (в Windows 2000) или Command.com (в Windows 98) -- типичные образцы подобных приложений.
Вместе с тем граница между двумя типами приложений весьма условна. Можно, например, создать консольное приложение, способное отображать диалоговые окна. Скажем, в командном процессоре вполне может быть специальная команда, открывающая графическое диалоговое окно со списком команд, вроде мелочь -- а избавляет от запоминания лишней информации. В то же время можно создать и GUI-приложение, выводящее текстовые строки в консольное окно. Я сам часто писал такие пpoграммы: создав консольное окно, я пересылал в него отладочную информацию, связанную с исполняемым приложением. Но, конечно, графический интерфейс предпочтительнее, чем старомодный текстовый. Как показывает опыт, приложения на основе GUI "дружественнее" к пользователю, а значит и более популярны.
Когда Вы создаете проект приложения, Microsoft Visual C++ устанавливает такие ключи для компоновщика, чтобы в исполняемом файле был указан соответствующий тип подсистемы Для CUI-программ используется ключ /SUBSYSTEM:CONSOLE, а для GUI-приложений -- /SUBSYSTEM:WINDOWS Когда пользователь запускает приложение, загрузчик операционной системы проверяет помер подсистемы, хранящийся в заголовке образа исполняемого файла, и определяет, что это за программа -- GUI или СUI Если номер указывает на приложение последнего типа, загрузчик автоматически создает текстовое консольное окно, а если номер свидетельствует о противоположном -- просто загружает программу в память После того как приложение начинает работать, операционная система больше не интересуется, к какому типу оно относится.
Во всех Windows-приложениях должна быть входная функция за реализацию которой отвечаете Вы Существует четыре такие функции:
int WINAPI WinMain( HINSTANCE hinstExe, HINSTANCE, PSTR pszCmdLine, int nCmdShow);
int WINAPT wWinMain( HINSTANCE hinstExe, HINSTANCE, PWSTR pszCmdLine, int nCmdShow);
int __cdecl main( int argc, char *argv[], char *envp[]);
int _cdecl wmain( int argc, wchar_t *argv[], wchar_t *envp[]);
На самом делс входная функция операционной системой не вызывается Вместо этого происходит обращение к стартовой функции из библиотеки С/С++ Она инициализирует библиотеку С/С++, чтобы можно было вызывать такие функции, как malloc и free, а также обеспечивает корректное создание любых объявленных Вами глобальных и статических С++-объектов до того, как начнется выполнение Вашего кода В следующей таблице показано, в каких случаях реализуются те или иные входные функции.
Таблица
Тип приложения |
Входная функция |
Стартовая функция, встраиваемая в Ваш исполняемый файл |
|
GUI-приложение, работающее с ANSI-символами и строками |
WinMain |
WinMainCRTStartup |
|
GUI-приложение, работающее с Unicode-символами и строками |
wWinMain |
wWinMainCRTStartup |
|
GUI-приложение, работающее с ANSI-символами и строками |
main |
mainCRTStartup |
|
GUI-приложение, работающее с Unicode-символами и строками |
wmain |
wmainCRTStartup |
Нужную стартовую функцию в библиотеке С/С++ выбирает компоновщик при сборке исполняемого файла. Если указан ключ /SUBSYSTEM:WINDOWS, компоновщик ищет в Вашем коде функцию WinMain или wWinMain, Если ни одной из них нет, он сообщает об ошибке "unresolved external symbol" ("неразрешенный внешний символ"); в ином случае -- выбирает WtnMainCRTStartup или wWinMainCRTStartup соответственно.
Аналогичным образом, если ладан ключ /SUBSYSTEM:CONSOLE, компоновщик ищет в коде функцию main или wmain и выбирает соответственно mainCRTStartup или wmainCRTStartup; если в коде нет ни main, ни wmain, сообщается о той же ошибке -- "unresolved external symbol"
Но не многие знают, что в проекте можно вообще не указывать ключ /SUBSYSTEM компоновщика. Если Вы так и сделаете, компоновщик будет сам определять подсистему для Вашего приложения. При компоновке он проверит, какая из четырех функций (WinMain, wWinMain, main или wmain) присутствует в Вашем коде, и на основа нии этого выберет подсистему и стартовую функцию из библиотеки С/С++.
Одна из частых ошибок, допускаемых теми, кто лишь начинает работать с Vi sual С++, -- выбор неверного типа проекта. Например, разработчик хочет создать проект Win32 Application, а сам включает в код функцию main При его сборке он получает сообщение об ошибке, так как для проекта Win32 Application в командной строке компоновщика автоматически указывается ключ /SUBSYSTEM:WlNDOWS, который требует присутствия в коде функции WinMain или wWinMatn В этот момент разработчик может выбрать один из четырех вариантов дальнейших действий:
· заменить main на WinMain Как правило, это не лучший вариант, поскольку разработчик скорее всего и хотел создать консольное приложение,
· открыть новый проект, на этот раз -- Win32 Console Application, и перенести в него все модули кода. Этот вариант весьма утомителен, и возникает ощущение, будто начинаешь все заново,
· открыть вкладку Link в диалоговом окне Project Settings и заменить ключ /SUBSYSTEM:WINDOWS на /SUBSYSTEM:CONSOLK. Некоторые думают, что это единственный вариант,
· открыть вкладку Link в диалоговом окне Project Settings и вообще убрать ключ /SUBSYSTEM:WINDOWS. Я предпочитаю именно этот способ, потому что он самый гибкий. Компоновщик сам сделает все, что надо, в зависимости от вход ной функции, которую Вы реализуете в своем коде, Никак не пойму, почему это не предлагается по умолчанию при создании нового проекта Win32 Application или Win32 Console Application.
Все стартовые функции из библиотеки С/С++ делают практически одно и то же. Разница лишь в том, какие строки они обрабатывают (в ANSI или Unicode) и какую входную функцию вызывают после инициализации библиотеки. Кстати, с Visual C++ поставляется исходный код этой библиотеки, и стартовые функции находятся в фай ле CRt0.c. А теперь рассмотрим, какие операции они выполняют:
· считывают указатель на полную командную строку нового процесса;
· считывают указатель на переменные окружения нового процесса;
· инициализируют глобальные переменные из библиотеки С/С++, доступ к которым из Вашего кода обеспечивается включением файла StdLib.h. Список этих переменных приведен в таблице 4-1;
· инициализируют кучу (динамически распределяемую область памяти), используемую С-функциями выделения памяти (т. с. malloc и calloc} и другими про цедурами низкоуровневого ввода-вывода;
· вызывают конструкторы всех глобальных и статических объектов С++-классов.
Закончив эти операции, стартовая функция обращается к входной функции в Вашей программе. Если Вы написали ее в виде wWinMain, то она вызывается так:
GetStartupInfo(&StartupInfo);
int nMainRetVal = wWinMain(GetMjduleHandle(NULL), NULL, pszCommandLineUnicode, (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) ? StartupInfo.wShowWindow, SW_SHOWDEFAULT);
А если Вы предпочли WinMain, то:
GetStartupInfo(&StartupInfo);
int nMainReLVal = WinMain(GetModuleHandle(NULL), NULL, pszCommandLineANSI, (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) ? Startupinfo.wShowWindow , SW_SHOWDEFAULT);
И, наконец, то же самое для функций wmain и main.
int nMainRetVal = wmain(__argc, __wargv, _wenviron}; int nMainRetVal = main(_argc, __argv, _environ);
Когда Ваша входняя функция возвращает управление, стартовая обращается к функции exit библиотеки С/С++ и передает ей значение nMainRetVal. Функция exit выполняет следующие операции:
· вызывает всс функции, зарегистрированные вызовами функции _onexit;
· вызывает деструкторы всех глобальных и статических объектов С++-классов;
· вызывает Windows-функцию ExifProcess, передавая ей значение nMainRetVal. Это заставляет операционную систему уничтожить Ваш процесс и установить код его завершения.
Имя переменной |
Тип |
Описание |
|
_osver |
unsigned int |
Версия сборки операционной системы. Например, у Windows 2000 Beta 3 этот номер был 2031,соответственно _osver равна 2031. |
|
_winmajor |
unsigned int |
Основной номер версии Windows в шестнадцатерич ной форме. Для Windows 2000 это значение равно 5. |
Таблица 4-1. Глобальные переменные из библиотеки С/С++, доступные Вашим программам
Имя переменной |
Тип |
Описание |
|
_winminor |
unsigned int |
Дополнительный номер версии Windows в шестнадца теричной форме Для Windows 2000 это значение равно 0 |
|
_winver |
unsigned int |
Вычисляется как ( winmajor << 8) + _winminor. |
|
__argc |
unsigned int |
Количество аргументов, переданных в командной строке |
|
__argv _ _wargv |
char ** wchar_t ** |
Массив размером __argc с указателями на ANSI- или Unicode-строки. Каждый элемент массива указывает на один из аргументов командной строки. |
|
_environ _wenviron |
char ** wchar_t ** |
Массив указателей на ANSI- или Unicode-строки. Каждый элемент массива указывает на строку -- переменную окружения. |
|
_pgmptr _wpgmptr |
char ** wchar_t** |
Полный путь и имя (в ANSI или Unicode) запускаемой программы. |
Описатель экземпляра процесса
Любому EXE- или DLL-модулю, загружаемому в адресное пространство процесса, присваивается уникальный описатель экземпляра. Описатель экземпляра Вашего EXE файла передается как первый параметр функции (w)WinMain - hinstExe. Это значение обычно требуется при вызовах функций, загружающих те или иные ресурсы. На пример, чтобы загрузить из образа ЕХЕ-файла такой ресурс, как значок, надо вызвать:
HICON LoadIcon( HINSTANCE hinst, PCTSTR pszIcori);
Первый параметр в LoadIcon указывает, в каком файле (EXE или DLL) содержится интересующий Вас ресурс. Многие приложения сохраняют параметр hinstExe функции (w)WinMain в глобальной переменной, благодаря чему он доступен из любой части кода ЕХЕ-файла.
В документации Platform SDK утверждается, что некоторые Windows-функции требуют параметр типа HMODULE. Пример -- функция GetModuleFileName
DWORD GetModuleFileName(HMODULE hinstModule, PTSTR pszPath, DWORD cchPath);
NOTE: Как оказалось, HMODULE и HINSTANCE -- это идно и то же. Встретив в документации указание передать какой-то функции HMODULE, смело передавайте HINSTANCE, и наоборот. Они существуют в таком виде лишь потому, что в l6-разрядной Windows идентифицировали совершенно разные вещи.
Истинное значение параметра hinstExe функции (w)WinMain -- базовый адрес в памяти, определяющий ту область в адресном пространстве процесса, куда был загружен образ данного ЕХЕ-файла, Например, если система открывает исполняемый файл и загружает его содержимое по адресу 0x00400000, то hinstExe функции (w)Win Main получает значение 0x00400000.
Базовый адрес, но которому загружается приложение, определяется компоновщиком. Разные компоновщики выбирают и разные (пo умолчанию) базовые адреса. Компоновщик Visual С++ использует по умолчанию базовый адрес 0x00400000 -- самый нижний в Windows 98, начиная с которого в ней допускается загрузка образа испол няемого файла. Указав параметр /BASE: адрес (в случае компоновщика от Microsoft), можно изменить базовый адрес, по которому будет загружаться приложение.
При попытке загрузить исполняемый файл в Windows 98 по базовому адресу ниже 0x00400000 загрузчик переместит его на другой адрес. Это увеличит время загрузки приложения, но оно по крайней мере будет выполнено. Если Вы разрабатываете про граммы и для Windows 98, и для Windows 2000, сделайте так, чтобы приложение заг ружалось по базовому адресу не ниже 0x00400000. Функция GetModuleHandle.
HMODULE GetModuleHandle( PCTSTR pszModule);
возвращает описатель/базовый адрес, указывающий, куда именно (в адресном пространстве процесса) загружается EXE- или DLL-файл. При вызове этой функции имя нужного EXE- или DLL-файла передается как строка с нулевым символом в конце. Если система находит указанный файл, GetModuleHandle возвращает базовый адрес, по которому располагается образ данного файла. Если же файл системой не найден, функция возвращает NULL. Кроме того, можно вызвать эту функцию, передав ей NULL вместо параметраpszModule, -- тогда Вы узнаете базовый адрес EXE-файла. Именно это и делает стартовый код из библиотеки С/С++ при вызове (w)WinMain из Вашей программы.
Есть еще две важные вещи, касающиеся GetModuleHandle. Во-первых, она проверяет адресное пространство только того процесса, который ее вызвал. Если этот процесс не использует никаких функций, связанных со стандартными диалоговыми окнами, то, вызвав GetModuleHandle и передав ей аргумент "ComDlg32", Вы получите NULL - пусть даже модуль ComDlg32.dll и загружен в адресное пространство какого-нибудь другого процесса. Во-вторых, вызов этой функции и передача ей NULL дает в результате базовый адрес ЕХЕ-файла в адресном пространстве процесса. Так что, вы зывая функцию в виде GetModuleHandle(NULL -- даже из кода в DLL, -- Вы получаете базовый адрес EXE-, а не DLL-файла.
Описатель предыдущего экземпляра процесса
Я уже говорил, что стартовый код из библиотеки С/С++ всегда передает в функцию (w)WinMain параметр binstExePrev как NULL. Этот параметр предусмотрен исключи тельно для совместимости с 16-разрядными версиями Windows и не имеет никакого смысла для Windows-приложений. Поэтому я всегда пишу заголовок (w)WinMain так:
int WINAPI WinMain( HINSTANCE hinstExe, HINSTANCE, PSTR pszCmdLine, int nCmdShow);
Поскольку у второго параметра нет имени, компилятор не выдает предупрежде ние "parameter not referenced" ("нет ссылки на параметр"),
Командная строка процесса
При создании новому процессу передается командная строка, которая почти никог да не бывает пустой -- как минимум, она содержит имя исполняемого файла, исполь зованного при создании этого процесса. Однако, как Вы увидите ниже (при обсужде нии функции CreateProcess), возможны случаи, когда процесс получает командную строку, состоящую из единственного символа -- нуля, завершающего строку. В момент запуска приложения стартовый код из библиотеки С/С++ считывает командную строку процесса, пропускает имя исполняемого файла и заносит в параметр pszCmdLine функции (w)WinMain указатель на оставшуюся часть командной строки.
Параметр pszCmdLine всегда указывает на ANSI-строку. Но, заменив WinMain на wWinMain, Вы получите доступ к Unicode-версии командной строки для своего про цесса
Программа может анализировать и интерпретировать командную строку как угодно. Поскольку pszCrndLine относится к типу PSTR, а не PCSTR, не стесняйтесь и записывайте строку прямо в буфер, на который указывает этот параметр, но ни при каких условиях не переступайте границу буфера. Лично я всегда рассматриваю этот буфер как "только для чтений". Если в командную строку нужно внести изменения, я снача ла копирую буфер, содержащий командную строку, в локальный буфер (в своей про грамме), который затем и модифицирую.
Указатель на полную командную строку процесса можно получить и вызовом функции GetCommandLine.
PTSTR GetCommandLine();
Она возвращает указатель на буфер, содержащий полную командную строку, вклю чая полное имя (вместе с путем) исполняемого файла.
Во многих приложениях безусловно удобнее использовать командную строку, предварительно разбитую на отдельные компоненты, доступ к которым приложение может получить через глобальные переменные _argc и _argv (или _wargu). Функ ция CommandLineToArgvW расщепляет Unicode-строку на отдельные компоненты:
PWSTR CommandLineToArgvW( PWSTR pszCmdLine, int pNumArgs);
Буква W в конце имени этой функции намекает на "широкие" (wide) символы и подсказывает, что функция существует только в Unicode-версии. Параметр pszCmdLine указывает на командную строку Его обычно получают предварительным вызовом GetCommandLineW Параметр pNumArgs -- это адрес целочисленной переменной, в которой задается количество аргументов в командной строке. Функция Command LineToArgvW возвращает адрес массива указателей на Unicode-строки
CommandLineToArgvW выделает нужную память автоматически. Большинство приложений не освобождает эту память, полагаясь на операционную систему, которая проводит очистку ресурсов по завершении процесса. И такой подход вполне приемлем. Нo если Вы хотите сами освободить эту память, сделайте так:
int pNumArgs; PWSTR *ppArgv = CommandLineToArgvW(GetCommandLineW(), &pNumArgs);
// используйте эти аргументы if (*ppArgv[1] == L x ) { // освободите блок памяти HeapFree(GetProcessHeap() 0 ppArgv);
Переменные окружения
С любым процессом связан блок переменных окружения -- область памяти, выделенная в адресном пространстве процесса. Каждый блок содержит группу строк такого вида
VarName1-VarValue1\0 VarName2-VarValue2\0 VarName3=VarValue3\0 ... VarNameX=VarValueX\0\0
Первая часть каждой строки -- имя переменной окружения. Зa ним следует знак равенства и значение, присваиваемое переменной Строки в блоке переменных окружения должны быть отсортированы в алфавитном порядке по именам переменных
Знак равенства разделяет имя переменной и ее значение, так что его нельзя использовать как символ в имени переменной Важную роль играют и пробелы. Например, объявив две переменные
XYZ= Windows (обратите внимание на пробел за знаком равенства) ABC=Windows
и сравнив значения переменных ХУZ и АВС, Вы увидите, что система их различает, -- она учитывает любой пробел, поставленный перед знаком равенства или после него. Вот что будет, если записать, скажем, так
XYZ =Home (обратите внимание на пробел перед знаком равенства) XYZ=Work
Вы получите первую переменную с именем "XYZ", содержащую строку "Home", и вторую переменную "XYZ", содержащую строку "Work"
Конец блока переменных окружения помечается дополнительным нулевым символом WINDOWS 98. Чтобы создать исходный набор переменных окружения для Windows 98, надо модифицировать файл Autoexec bat, поместив в него группу строк SET в виде
SET VarName=VarValue
При перезагрузке система учтет новое содержимое файла Autoexecbat, и тогда любые заданные Вами переменные окружения станут доступны всем процессам, инициируемым в сеансе работы с Windows 98.
WINDOWS 2000 При регистрации пользователя на входе в Windows 2000 система создает npoцесс-оболочку, связывая с ним группу строк -- переменных окружения. Система получает начальные значения этих строк, анализируя два раздела в реестpe. В первом:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ SessionManager\Environment
содержится список переменных окружения, относящихся к системе, а во втором:
HKEY_CURRENT_USER\Environment
находится список переменных окружения, относящихся к пользователю, который в настоящее время зарегистрирован в системе.
Пользователь может добавлять, удалять или изменять любые переменные через апплет System из Control Panel B этом апплете надо открыть вкладку Advanced и щелкнуть кнопку Environment Variables -- тогда на экране появится следующее диалоговое окно.
Модифицировать переменные из списка System Variables разрешается только пользователю с правами администратора.
Кроме того, для модификации записей в реестре Ваша программа может обращаться к Windows-функциям, позволяющим манипулировать с реестром. Однако, чтобы изменения вступили в силу, пользователь должен выйти из системы и вновь войти в нее. Некоторые приложения типа Explorer, Task Manager или Control Pancl могут обновлять свои блоки переменных окружения на базе новых значений в реестре, когда их главные окна получают сообщение WM_SET TINGCHANGE, Например, если Вы, изменив реестр, хотите, чтобы какие-то приложения соответственно обновили свои блоки переменных окружения, вызовите
SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE 0, (LPARAM) TEXT("Envnuntnent"))
Обычно дочерний процесс наследует набор переменных окружения от родительского. Однако последний способен управлять чем, какие переменные окружения наследуются дочерним процессом, а какие -- нет. Но об этом я расскажу, когда мы займемся функцией CreateProcess. Под наследованием я имею в виду, что дочерний процесс получает свою копию блока переменных окружения от родительского, а не то, что дочерний и родительский процессы совместно используют один и тот же блок, Так что дочерний процесс может добавлять, удалять или модифицировать переменные в своем блоке, и эти изменения не затронут блок, принадлежащий родительскому процессу.
Переменные окружения обычно применяются для тонкой настройки приложения. Пользователь создает и инициализирует переменную окружения, затем запускает приложение, и оно, обнаружив эту переменную, проверяет ее значение и соответствующим образом настраивается.
Увы, многим пользователям не под силу разобраться в переменных окружения, а значит, трудно указать правильные значения. Ведь для этого надо не только хорошо знать синтаксис переменных, но и, конечно, понимать, что стоит за теми или иными их значениями. С другой стороны, почти все (а может, и все) приложения, основанные на GUI, дают возможность тонкой настройки через диалоговые окна. Такой подход, естественно, нагляднее и проще.
А теперь, если у Вас еще не пропало желание манипулировать переменными окружения, поговорим о предназначенных для этой цели функциях. GetEnvironment Variableпозволяет выявлять присутствие той или иной переменной окружения и определять ее значение:
DWORD GetEnvironment Variable( PCTSTR pszName, PTSTR pszValue, DWORD cchValue);
При вызове GetEnvironmentVariable параметр pszName должен указывать на имя интересующей Вас переменной, pszValue -- на буфер, в который будет помещено значение переменной, а в cchValue следует сообщить размер буфера в символах. Функция возвращает либо количество символов, скопированных в буфер, либо 0, если ей не удалось обнаружить переменную окружения с таким именем.
Кстати, в реестре многие строки содержат подставляемые части, например.
%USERPROFILE%\My Documents
Часть, заключенная в знаки процента, является подставляемой. В данном случае в строку должно быть подставлено значение переменной окружения USERPROFILE На моей машине эта переменная выглядит так:
C:\Documents and Settings\Administrator
После подстановки переменной в строку реестра получим
C:\Documents and Settings\Admimstrator\My Documents
Поскольку такие подстановки делаются очень часто, в Windows есть функция ExpandEnvironmentStrings.
DWORD ExpandEnvironmentStrings( PCTSTR pszSrc, PTSTR pszDst, DWORD nSize);
Параметр pszSrc принимает адрес строки, содержащей подставляемые части, а параметр pszDsf -- адрес буфера, в который записывается развернутая строка Пара метр nSize определяет максимальный размер буфера в символах.
Наконец, функция SetEnvironmentVariable позволяет добавлять, удалять и модифи цировать значение переменной
DWORD SetEnvironmentVariable( PCTSTR pszName, PCTSTR pszValue);
Она устанавливает ту переменную, на чье имя указывает параметр pszName, и присваивает ей значение, заданное параметром pszValue. Если такая переменная уже существует, функция модифицирует ее значение. Если же spszValue содержится NULL, переменная удаляется из блока
Для манипуляций с блоком переменных окружения всегда используйте именно эти функции. Как я уже говорил, строки в блоке переменных нужно отсортировать в алфавитном порядке по именам псрсмснных (тогда GetEnvironmentVariable быстрее находит нужные переменные), a SetEnvironmentVariable как раз и следит за порядком расположения переменных.
Привязка к процессорам
Обычно потоки внутри процесса могут выполняться на любом процессоре компьютера. Однако их можно закрепить за определенным подмножеством процессоров из числа имеющихся на компьютере. Это свойство называется привязкой к процессорам (processor affinity) и подробно обсуждается в главе 7. Дочерние процессы наследуют привязку к процессорам от родительских.
Режим обработки ошибок
С каждым процессом связан набор флагов, сообщающих системе, каким образом процесс должен реагировать на серьезные ошибки: повреждения дисковых носителей, необрабатываемые исключения, ошибки операций поиска файлов и неверное выравнивание данных. Процесс может указать системе, как обрабатывать каждую из этих ошибок, через функцию SetErrorMode\
UINT SetErrorMode(UINT fuErrorMode) ;
Параметр fuErrorMode -- это набор флагов, комбинируемых побитовой операцией OR
Флаг |
Описание |
|
SEM FAILCRITICALERRORS |
Система не выводит окно с сообщением от обработчика критических ошибок и возвращает ошибку в вызывающий процесс |
|
SEM_NOGPFAULTERRORBOX |
Система не выводит окно с сообщением о нарушении общей защиты; этим флагом манипулируют только отладчики, самостоятельно обрабатывающие нарушения общей защиты с помощью обработчика исключений |
|
SEM_NOOPENFILEERRORBOX |
Система не выводит окно с сообщением об отсутствии искомого файла |
|
SEM_NOALIGNMENTFAULTEXCEPT |
Система автоматически исправляет нарушения в выравнивании данных, и они становятся невидимы приложению: этот флаг не действует на процессорах x8б |
По умолчанию дочерний процесс наследует от родительского флаги, указывающие на режим обработки ошибок. Иначе говоря, если у процесса в данный момент установлен флаг SEM_NOGPFAULTERRORBOX и он порождает другой процесс, этот
флаг будет установлен и у дочернего процесса. Однако "наследник" об этом не уведомляется, и он вообще может быть нс рассчитан на обработку ошибок такого типа (к данном случае -- нарушений общей защиты). В результате, если в одном из потоков дочернего процесса все-таки произойдет подобная ошибка, этот процесс может завершиться, ничего не сообщив пользователю. Но родительский процесс способен предотвратить наследование дочерним процессом своего режима обработки ошибок, указав при вызове функции CreateProcess флаг CREATE_DEFAULT_ERROR_MODE (о CreateProcess чуть позже).
Текущие диск и каталог для процесса
Текущий каталог текущего диска -- то место, где Windows-функции ищут файлы и подкаталоги, если полные пути в соответствующих параметрах не указаны. Например, если поток в процессе вызывает функцию CreateFile, чтобы открыть какой-нибудь файл, а полный путь не задан, система просматривает список файлов в текущем ката логе текущего диска. Этот каталог отслеживается самой системой, и, поскольку такая информация относится ко всему процессу, смена текущего диска или каталога одним из потоков распространяется и на остальные потоки в данном процессе.
Поток может получать и устанавливать текущие каталог и диск для процесса с помощью двух функций:
DWORD GetCurrentDirectory( DWORD cchCurDir, PTSTR pszCurDir);
BOOL SetCurrentDirectory(PCTSTR pszCurDir);
Текущие каталоги для процесса
Система отслеживает текущие диск и каталог для процесса, но не текущие каталоги на каждом диске. Однако в операционной системе предусмотрен кое-какой сервис для манипуляций с текущими каталогами на разных дисках. Он реализуется через переменные окружения конкретного процесса. Например:
=C:=C-\Utility\Bin =D:=D:\Program Files
Эти переменные указывают, что текущим каталогом на диске С является \Utllity\ Bin, а на диске D -- Program Files.
Если Вы вызываете функцию, передавая ей путь с именем диска, отличного от текущего, система сначала просматривает блок переменных окружения и пытается найти переменную, связанную с именем указанного диска. Если таковая есть, система выбирает текущий каталог на заданном диске в соответствии с ее значением, нет -- текущим каталогом считается корневой.
Скажем, если текущий каталог для процесса -- C:\Uiiltty\Bin и Вы вызываете функцию CreateFile, чтобы открыть файл D:\ReadMe.txt, система ищет переменную =D:. Поскольку переменная =D: существует, система пытается открыть файл ReadMe txt в каталоге D:\Program Files. А если бы таковой переменной не было, система искала бы файл ReadMe.txt в корневом каталоге диска D. Кстати, файловые Windows-функции никогда не добавляют и не изменяют переменные окружения, связанные с именами дисков, а лишь считывают их значения.
NOTE: Для смены текущего каталога вместо Windows-функции SetCurrentDirectory можно использовать функцию _chdir из библиотеки С Внутренне она тоже обращается к SetCurrentDirettory, но, кроме того, способна добавлять или модифицировать переменные окружения, что позволяет запоминать в программе текущие каталоги на различных дисках.
Если родительский процесс создает блок переменных окружения и хочет передать его дочернему процессу, тот не наследует текущие каталоги родительского процесса автоматически. Вместо этого у дочернего процесса текущими на всех дисках становятся корневые каталоги. Чтобы дочерний процесс унаследовал текущие каталоги родительского, последний должен создать соответствующие переменные окружения (и сделать это до порождения другого процесса). Родительский процесс может узнать, какие каталоги являются текущими, вызвав GetFullPathName:
DWORD GetFullPathName( PCTSTR pszFile, DWORD cchPath, PTSTR pszPath, PTSTR *ppszFilePart);
Например, чтобы получить текущий каталог на диске С, функцию вызывают так:
TCHAR szCurDir[MAX_PATH];
DWORD GetFullPathName(TEXT("C."), MAX_PATH, szCurDir, NULL);
Не забывайте, что переменные окружения процесса должны всегда храниться в алфавитном порядке Поэтому переменные, связанные с дисками, обычно приходится размещать в самом начале блока.
Определение версии системы
Весьма часто приложению требуется определять, в какой версии Windows оно выполняется. Причин тому несколько. Например, программа может использовать функции защиты, заложенные в Windows API, но в полной мере эти функции реализованы лишь в Windows 2000.
Насколько я помню, функция GetVersion есть в API всех версий Windows:
DWORD GetVersion();
С этой простой функцией связана целая история. Сначала ее разработали для 16 разрядной Windows, и она должна была я старшем слове возвращать номер версии MS-DOS, а в младшем -- номер версии Windows. Соответственно в каждом слове старший байт сообщал основной номер версии, младший -- дополнительный но мер версии
Увы, программист, писавший ее код, слегка ошибся, и получилось так, что номера версии Windows поменялись местами: в старший байт попадал дополнительный но мер, а в младший - основной. Поскольку многие программисты уже начали пользоваться этой функцией, Microsoft пришлось оставить все, как есть, и изменить документацию с учетом ошибки.
Из-за всей этой неразберихи вокруг GetVersion в Windows API включили новую функцию -- GetVersionEx:
BOOL GetVersionEx(POSVERSIONINFO pVersionInformation);
Перед обращением к GetVersionEx профамма должна создать структуру OSVER SIONINFOEX, показанную ниже, и передать ее адрес этой функции
typedef struct { DWORD dwOSVersionInfoSize;DWORD dwMajorVersion;DWORD dwMinorVersion;DWORD dwBuildNumber;DWORD dwPlatformId;TCHAR szCSDVersion[128];WORD wServicePackMajor;WORD wServicePackMinor;WORD wSuiteMask;BYTE wProductType; BYTE wReserved;} OSVERSIONINFOEX, *POSVERSIONINFOEX;
Эта структура -- новинка Windows 2000 В остальных версиях Windows используется структура OSVERSIONINFO, в которой нет последних пяти элементов, присутствующих в структуре OSVERSIONINFOEX
Обратите внимание, что каждому компоненту номера версии операционной системы соответствует свой элемент структуры это сделано специально -- чтобы программисты не возились с выборкой данных всяких там старших-младших байтов слов (и не путались в них), тeпepь программе гораздо проще сравнивать ожидаемый номер версии операционной системы с действительным Назначение каждою элемента структуры OSVERSIONTNFOFX описано в таблице 4-2
Таблица 4-2. Элементы структуры OSVERSIONINFOEX
Элемент |
Описание |
|
dwOSVersionInfoSjze |
Размер структуры, перед обращением к функции GetVertsionEx дол жен быть заполнен вызовом sizeof(OSVERSIONINFO) или Sizeof(OSVERSIONINFOEX) |
|
dwMajorVersion |
Основной номер версии операционной системы |
|
dwMinorVersion |
Дополнительный номер версии операционной системы |
|
dwBuildNumber |
Версия сборки данной системы |
|
dwPlatformId |
Идентификатор платформы, поддерживаемой данной системой, его возможные шачепия VFR_PLATFORM_WIN32s (Win32s), VER_PLATFORM_WIN32_WINDOWS (Windows 95/98), VER_PLATFORM_WIN32_NT (Windows NT или Windows 2000), VER_PLATFORM_WIN32_CEHH (Windows CE) |
|
szCSDVersion |
Этот элемент содержит текст -- дополнительную информацию об установленной операционной системе |
|
wServicePackMajor |
Основной номер версии последнего установленного пакета исправ лений (service pack) |
|
wServicePackMinor |
Дополнительный номер версии последнего установленного пакета исправлений |
|
Элемент |
Описание |
|
wSuiteMask |
Сообщает, какие программные пакеты (suites) доступны в системе; его возможные значения VER_SUITE_SMALLBUSINESS, VER_SUITE_ENTERPRISE, VER_SUITE_BACKOFFICE, VER_SUITE_COMMUNICATIONS, VER_SUITE_TERMINAL, VER_SUITE_SMALLBUSINESS_RESTRICTED, VER_SUITE_EMBEDDEDNT, VER_SUITE_DATACENTER |
|
wProductType |
Сообщает, какой именно вариант операционной системы установлен; его возможные значения: VER_NT_WORKSTATION, VER_NT_SERVER, VER_NT_DOMAIN_CONTROLLER |
|
wReserved |
Зарезервирован на будущее |
В Windows 2000 появилась новая функция, VerifyVersionInfo, которая сравнивает версию установленной операционной системы с тем, что требует Ваше приложение:
BOOL VerifyVersionInfo( POSVERSIONINFOEX pVersionInformation;DWORD dwTypeMask;DWORDLONG dwlConditionMask);
Чтобы использовать эту функцию, соэдайте структуру OSVERSIONINFOEX, запи шите в се элемент dwOSVersionInfoSize размер структуры, а потом инициализируйте любые другие элементы, важные для Вашей программы, При вызове VerifyVersionInfo параметр dwTypeMask указывает, какие элементы структуры Вы инициализировали. Этот параметр принимает любые комбинации следующих флагов:
VER_MINORVER SION, VER_MAJORVERSION, VER_BUILDNUMBER, VER_PLATFORMID, VER_SERVICEPACK MINOR, VER_SERVICEPACKMAJOR, VER_SUITENAME и VER_PRODUCT_TYPE,
Последний параметр, dwlConditionMask, является 64-разрядным значением, которое управляет тем, как именно функция сравнивает информацию о версии системы с нужными Вам дан ными.
Параметр dwlConditionMask устанавливает правила сравнения через сложный на бор битовых комбинаций. Для создания требуемой комбинации используйте макрос VER_SET_CONDITION:
VER_SET_CONDITION( DWORDLONG dwlConditionMask, ULONG dwTy0eBiLMask, ULONG dwConditionMask);
Первый параметр, dwlConditionMask, идентифицирует переменную, битами которой Вы манипулируете. Вы не передаете адрес этой переменной, потому что VER_SET_ CONDITION -- макрос, а не функция. Параметр dwTypeBitMask указывает один элемент в структуре OSVERSIONINFOEX, который Вы хотите сравнить со своими данными. (Для сравнения нескольких элементов придется обращаться к VER_SETCONDITION несколько раз подряд.) Флаги, передаваемые в этом параметре, идентичны передаваемым в параметре dwTypeMask функции VerifyVersionInfo.
Последний параметр макроса VER_SET_CONDITION, dwConditionMask, сообщает, как Вы хотите проводить сравнение. Он принимает одно из следующих значений. VER_EQUAL, VER_GREATER, VER_GREATER_EQUAL, VER_LESS или VER_LESS_EQUAL, Вы можете использовать эти значения в сравнениях по VER_PRODUCT_TYPE. Например, значение VER_NT_WORKSTATION меньше, чем VER_NT_SERVER. Но в сравнениях по VER_SUITENAME вместо этих значений применяется VER_AND (должны быть установлены все программные пакеты) или VER_OR (должен быть установлен хотя бы один из программных пакетов).
Подготовив набор условий, Вы вызываете VerifyVersionlnfo и получаете ненулевое значение, если система отвечает требованиям Вашего приложения, или 0, если она не удовлетворяет этим требованиям или если Вы неправильно вызвали функцию Чтобы определить, почему VenfyVersionlnfo вернула 0, вызвала GetLastError. Если та вернет ERROR_OLD_WIN_VERSION, значит, Вы правильно вызвали функцию Venfy VersionInfo, но система не соответствует предъявленным требованиям.
Вот как проверить, установлена ли Windows 2000;
// готовим структуру OSVERSIONINFOEX, сообщая, что нам нужна Windows 2000 OSVERSIONINFOEX osver = { 0 }; osver.dwOSVersionInfoSize = sizeof(osver); osver.dwMdjorVersion = 5; osver.dwMinorVersion = 0; osver.dwPlatformId = VER_PLATFORM_WIN32_NT;
// формируем маску условии
DWORDLONG dwlConditionMask = 0; // всегда инициализируйте это элемент так VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL);VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL); VER_SET_CONDITION(dwlConditionMask, VER_PLATFORMID, VER_EQUAL);
// проверяем версию if (VenfyVersionInfo(&osver, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, dwlConditionMask)) {
// хост-система точно соответствует Windows 2000
} else { // хост-система не является Windows 2000 }
Завершение процесса
Процесс можно завершить четырьмя способами:
· входная функция первичного потока возвращает управление (рекомендуемый способ),
· один из потоков процесса вызывает функцию ExitProcess (нежелательный спо соб);
· поток другого процесса вызывает функцию TerminateProcess (тоже нежелательно);
· все потоки процесса умирают по своей воле (большая редкость),
В этом разделе мы обсудим только что перечисленные способы завершения процесса, а также рассмотрим, что на самом деле происходит в момент его окончания.
Заключение
операционный программирование приложение
при завершении процесса
1. Выполнение всех потоков в процессе прекращается
2. Все User- и GDI-объекты, созданные процессом, уничтожаются, а объеюы ядра закрываются (если их не использует другой процесс).
3. Код завершения процесса меняется со значения STILL_ACTIVE на код, передан ный в ExitProcess или TerminateProcess.
4. Объект ядра "процесс" переходит в свободное, или незанятое (signaled), состояние (Подробнее на эту тему см главу 9 ) Прочие потоки в системе могут при остановить свое выполнение вплоть до завершения данного процесса.
5. Счетчик объекта ядра "процесс" уменьшается на 1
Связанный с завершаемым процессом объект ядра не высвобождается, пока не будут закрыты ссылки на него и из других процессов. В момент завершения процесса система автоматически уменьшает счетчик пользователей этого объекта на 1, и объект разрушается, как только его счетчик обнуляется. Кроме того, закрытие процесса не приводит к автоматическому завершению порожденных им процессов
По завершении процесса его код и выделенные ему ресурсы удаляются из памяти. Однако область памяти, выделенная системой для объекта ядра "процесс", не освобождается, пока счетчик числа его пользователей не достигнет нуля. А это произойдет, когда все прочие процессы, создавшие или открывшие описатели для ныне покойного процесса, уведомят систему (вызовом CloseHandle) о том, что ссылки па этот процесс им больше не нужны.
Описатели завершенного процесса уже мало на что пригодны. Разве что родительский процесс, вызвав функцию GetExitCodeProcess, может проверить, завершен ли процесс, идентифицируемый параметром hProcess, и, если да, определить код завершения:
BOOL GetExitCodeProcess( HANDLE hProcess, PDWORD pdwExitCode);
Код завершения возвращается как значение типа DWORD, на которое указывает pdwExitCode. Если на момент вызова GetExitCodeProcessпроцесс еще не завершился, в DWORD заносится идентификатор STILL_ACTIVE (определенный как 0x103) А если он уничтожен, функция возвращает реальный код его завершения.
Список литературы
1. Филатов, O.K. Информатизация современных технологий обучения в высшей школе / O.K. Филатов. --Ростов-на-Дону: б.и., 1997. -- 212 с.
2. Концепция информатизации высшего образования Российской Федерации. --М.: б.и., 1993. -- 226 с.
3. Информатика: энциклопедический словарь для начинающих / сост. Д.А. Поспелов -- М.: Педагогика-Пресс, 1994. -- 352 с.
4. Готлиб, М. Структура АОС / М. Готлиб // Информатика и образование.1987. -- № 3. -- С. 11-13.
5. Терских, В. Автоматизированные обучающие системы: концепция промышленного создания / В. Терских // Информатика и образование. -- 1987.1. --С. 3-15.
6. Кручинин, В.В. Разработка компьютерных учебных программ / В.В. Кручинин. -- Томск : Изд-во Том. ун-та, 1998. -- 211с.
7. Петрушин, В.А. Авторская система для создания электронных энциклопедий / В.А. Петрушин // Тез. докл. Междунар. конф. «Восток-Запад по новым информационным технологиям в образовании». -- М., 1992. -- С. 68-69.
8. Алексеенко, Е.А. СПОК-система программирования и поддержания обслуживающих и обучающих курсов / Е.А. Алексеенко, А.М. Довгялло, И.Х. Косая // Управляющие системы и машины. -- 1978. -- № 2. -- С. 127-128.
9. Новиков, В. АОС в вузе / В. Новиков, М. Орехов // Информатика и образование. -- 1987. -- № 2. -- С. 74-82.
10. Новиков, В. А. Типовые пакеты прикладных программ для автоматизированных обучающих систем / В.А. Новиков. -- М.: НИИВШ, 1985.1. Вып. 8. -- 44 с.
11. Савельев, А .Я. Подготовка информации для автоматизированных обучающих курсов / А .Я. Савельев, В.А. Новиков, Ю.И. Лобанов. -- М.: Высш. шк., 1986.--176 с.
Размещено на Allbest.ru
Подобные документы
Основные структуры процессов в операционной системе Unix. Возможные состояния процесса в Unix и способы перехода между ними. Планирование и выполнение процессов. Различия между родительским и дочерним процессом. Ожидание завершения и выполнения процесса.
курсовая работа [673,0 K], добавлен 24.02.2012Взаимодействие процессов и потоков в операционной системе, основные алгоритмы и механизмы синхронизации. Разработка школьного курса по изучению процессов в операционной системе Windows для 10-11 классов. Методические рекомендации по курсу для учителей.
дипломная работа [3,2 M], добавлен 29.06.2012Рассмотрение способов просмотра состояния процессов через диспетер задач в операционной системе Windows: определение взаимосвязи процессов и потоков, времени работы системы в пользовательском режиме. Ознакомление со сведениями о файлах драйверов.
лабораторная работа [3,1 M], добавлен 07.04.2010Рассмотрение понятия, назначения и преимуществ использования динамических библиотек; способы их связи с приложениями. Принципы работы с системным реестром Windows NT. Характеристика процессов и потоков как основополагающих компонент операционной системы.
лабораторная работа [760,6 K], добавлен 08.09.2011Управление процессами операционных систем. Разработка программы, моделирующей обслуживание множества вычислительных процессов в системе с 4 очередями, определяемыми значениями приоритетов. Выполнение инструкций компьютерной программы на процессоре.
контрольная работа [302,7 K], добавлен 06.08.2013Основы программирования в операционной системе Windows. Создание процессов в 32-битных операционных системах. Основное отличие дескриптора от идентификатора. Понятие критической секции. Основы вызова API-функций. Методы многозадачного программирования.
курсовая работа [501,1 K], добавлен 18.05.2014Понятие процесса и потока, характеристика их свойств и особенности создания. Требования к алгоритмам синхронизации, суть взаимного исключения на примере монитора и семафора. Методика изучения элективного курса "Процессы в операционной системе Windows".
дипломная работа [1,7 M], добавлен 03.06.2012Программные средства и системы для создания, автоматизирования технологических процессов. Разработка технологического процесса в системе "Вертикаль". Создание 3D моделей операционных заготовок в системе "Catia", технологической оснастки в "Solid Works".
дипломная работа [6,1 M], добавлен 25.06.2012Операционная система в роли связующего звена между аппаратурой компьютера и выполняемыми программами. Управление процессами операционной системы. Операционная система Windows. Различные виды Windows для определенных задач пользователей, их отличия.
реферат [28,5 K], добавлен 23.01.2012Знакомство с техническими характеристиками персонального компьютера. Установка операционной системы и драйверов Windows 7. Способы чистки Windows XP Professional SP3. Методы восстановления операционной системы. Выполнение установки Microsoft Office 2010.
отчет по практике [5,6 M], добавлен 22.09.2014