- •Операционные системы Windows32
- •Объекты ядра Windows
- •Пользователи объектов ядра
- •Защита объектов ядра
- •Дескрипторы. Таблица дескрипторов объектов ядра.
- •Создание объектов ядра
- •Закрытие объектов ядра
- •Совместное использование объектов ядра различными процессами
- •Процессы и потоки в Windows Создание процесса
- •Завершение процесса
- •Операции с процессами
- •Создание потока
- •Завершение потока
- •Потоки и библиотека языка с
- •Операции с потоками
- •Приоритеты потоков в Windows
- •Потоки в мультипроцессорных системах
- •Синхронизация потоков
- •Interlocked-функции
- •Критические секции
- •Wait-функции
- •Wait-функции для работы с одним объектом
- •Wait-функции для работы с несколькими объектами.
- •Побочные эффекты ожидания.
- •События
- •Семафоры
- •Мьютексы
- •Ожидаемые таймеры
- •Управление памятью в Windows
- •Организация виртуальной памяти Windows
- •Выделение памяти процессу
- •Атрибуты защиты страниц памяти
- •Функции менеджера памяти Windows
- •Проецируемые в память файлы
- •Проекции файлов и разделяемая память
Операции с процессами
Рассмотрим некоторые функции, которые позволяют манипулировать объектами типа процесс. Прежде всего, нам может потребоваться получить дескриптор собственного процесса. Сделать это позволяет функция GetCurrentProcess:
HANDLE GetCurrentProcess(VOID);
Эта функция возвращает дескриптор процесса, который может использоваться только внутри этого процесса, как и другие дескрипторы системных объектов. Сами процессы однако, имеют и общесистемные идентификаторы, которые позволяют обращаться к одному процессу из другого. Для того чтобы узнать такой идентификатор нашего процесса нужно использовать функцию GetCurrentProcessID:
DWORD GetCurrentProcessId(VOID);
Зная идентификатор какого-то другого процесса, мы можем получить к нему доступ с помощью функции OpenProcess:
HANDLE OpenProcess(
DWORD dwDesiredAccess, // access flag
BOOL bInheritHandle, // handle inheritance option
DWORD dwProcessId // process identifier
);
Получив тем или иным образом дескриптор процесса, мы можем обращаться к различным функциям Windows API, которые позволяют узнавать статистическую информацию о процессе, получать и устанавливать приоритет процесса и выполнять некоторые другие операции. Например, после завершения процесса мы можем узнать его код завершения с помощью функции GetExitCodeProcess:
BOOL GetExitCodeProcess(
HANDLE hProcess, // handle to the process
LPDWORD lpExitCode // termination status
);
Создание потока
При создании процесса автоматически создается и поток, выполняющий программу. Однако нам может потребоваться создать дополнительные потоки. Создание потока осуществляется вызовом функции CreateThread:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
SIZE_T dwStackSize, // initial stack size
LPTHREAD_START_ROUTINE lpStartAddress,// thread function
LPVOID lpParameter, // thread argument
DWORD dwCreationFlags, // creation option
LPDWORD lpThreadId // thread identifier
);
Параметр dwStackSize позволяет задать размер стека для создаваемого потока. Если указать значение 0, то система использует значение по умолчанию (1 мегабайт).
Наиболее интересным параметром этой функции является параметр lpStartAddress, который задает адрес функции, которая будет выполняться в потоке. Эта функция должна быть объявлена следующим образом:
DWORD WINAPI ThreadProc(
LPVOID lpParameter // thread data
);
Функции потока можно передать один параметр lpParameter, который может, например, являться указателем на структуру данных, содержащую все необходимые для потока параметры.
Параметр dwCreationFlag определяет режим создания потока. Если передать значение 0, то будет создан поток, который сразу начнет выполнение. Значение CREATE_SUSPENDED приведет к созданию потока, который находится в состоянии ожидания (и не выполняется).
Завершение потока
Также как и в случае завершения процесса, наиболее корректным способом завершения потока является возврат управления из функции потока. В случае необходимости аварийного завершения потока можно использовать функции ExitThread и TerminateThread:
VOID ExitThread(
DWORD dwExitCode // exit code for this thread
);
BOOL TerminateThread(
HANDLE hThread, // handle to thread
DWORD dwExitCode // exit code
);
Первая из этих функций завершает текущий поток, а вторая позволяет завершить любой поток в системе (к которому у Вас есть доступ).