- •Глава 2. Синхронизация задач с использованием api-функций и механизмов ядра.
- •§0. Объекты ядра. Основы.
- •Учет пользователей объектов ядра
- •Процесс и поток: краткая характеристика
- •Создание объекта ядра
- •Закрытие объекта ядра
- •Синхронизация объектов
- •Наследование описателей объекта
- •Именованные объекты
- •3. После этого вызова система проверяет, существует ли уже объект ядра с таким же именем. Если существует, то
- •Open-функции
- •Дублирование описателей объектов
- •1) Процесс-катализатор.
- •2) Процесс-источник.
- •3) Процесс-приемник.
- •Исходное состояние
- •1 0XF0000000 (неприм.) (неприм.)
- •1 0XF0000000 (неприм.) (неприм.)
- •Состояние после вызова DuplicateHandle
- •§1. Синхронизация задач с использованием функций ожидания.
- •Функция ожидания одного объекта
- •Функция ожидания нескольких объектов
- •Функция ожидания нескольких объектов и сообщений
- •Функция создания дочернего процесса
- •Функция завершения дочернего процесса из самого дочернего процесса
- •Функция завершения дочернего процесса из процесса родителя
- •Функция создания вторичного потока
- •Функция завершения дочернего потока из самого дочернего потока (only c)
- •Функция завершения дочернего потока из потока родителя
- •If (my_file.Is_open()) { /// Если удалось открыть
- •Функция создания вторичного потока _beginthread
- •Функция создания вторичного потока _beginthreadex
- •§2. Синхронизация задач с помощью объектов ядра «событие» (Event).
- •Функция создания события
- •Функция установки сигнального состояния события
- •Функция установки несигнального состояния события
- •Функция открытия существующего именованного объекта события
- •Дескриптор защиты (структура)
- •§3. Синхронизация задач с помощью объектов ядра «семафор» (Semaphore).
- •Функция создания семафора
- •Функция открытия семафора
- •Функция увеличения счетчика семафора на указанное количество
- •If (!ReleaseSemaphore( ghSemaphore, 1, null)) /// Если ошибка
- •§4. Синхронизация задач с помощью объектов ядра «мьютекс» (Mutex).
- •Функция создания мьютекса
- •Функция открытия существующего именованного объекта мьютекса
- •Функция освобождения владельца указанного объекта мьютекса
- •§5. Синхронизация задач с помощью объектов ядра «уведомление об изменении» (Change Notification).
- •Функция создания объекта ядра «уведомление об изменении»
- •Функция перезапуска объекта ядра «уведомление об изменении»
- •Функция остановки мониторинга дескриптора объекта ядра «уведомление об изменении»
- •§6. Синхронизация задач с помощью объектов ядра «таймер ожидания» (Waitable Timer).
- •Функция создания объекта ядра «таймер ожидания»
- •Функция активации объекта ядра «ожидаемый таймер»
- •Функция открытия объекта ядра «ожидаемый таймер»
- •1. Функцией CancelWaitableTimer().
- •2. Функцией SetWaitableTimer().
- •If (bSuccess) /// Если успешно, то
- •If (bSuccess) /// Если успешно, то
- •§7. Синхронизация задач с помощью объектов ядра «канал» (Pipe).
- •Анонимный канал
- •Создание анонимных каналов
- •Соединение клиентов с анонимным каналом
- •Обмен данными по анонимному каналу
- •Именованный канал
- •Функция создания именованного канала
- •Функция соединения сервера с клиентом
- •Отключение сервера от клиента
- •Функция ожидания операции именованного канала
- •Функция объединения функций именованного канала
- •Подключение клиента к серверу
Функция создания дочернего процесса
BOOL CreateProcess(
PCTSTR pszApplicationName,
PTSTR pszCommandLine,
PSECURITY_ATTRIBUTES psProcessAttr,
PSECURITY_ATTRIBUTES psThreadAttr,
BOOL bInheritHandles,
DWORD fdwCreate,
PVOID pvEnvironment,
PCTSTR pszCurDir,
PSTARTUPINFO psiStartInfo,
PPROCESS_INFORMATION ppiProcInfo
);
Функция завершения дочернего процесса из самого дочернего процесса
void ExitProcess(
IN UINT uExitCode /// Код возврата
);
Функция завершения дочернего процесса из процесса родителя
Функция обычно вызывается в процессе-родителе, который создал дочерний процесс.
BOOL TerminateProcess(
IN HANDLE hProcess, /// Handle
IN UINT uExitCode /// Код возврата
); /// TRUE, если успешно, иначе FALSE
Краткое описание.
При вызове CreateProcess система создает объект ядра «процесс» с начальным значением счетчика числа его пользователей, равным 1. Затем система создает для нового процесса виртуальное адресное пространство и загружает в это пространство код и данные как для исполняемого файла, так и для любых DLL (если таковые требуются).
Далее система формирует объект ядра «поток» (со счетчиком, равным 1) для первичного потока нового процесса. Как и в первом случае, объект ядра «поток» — это компактная структура данных, через которую система управляет потоком. Первичный поток начинает выполнение стартового кода из библиотеки C/C++, который в конечном счете вызывает функцию WinMain, wWinMain, main или wmain в Вашей программе. Если системе удастся создать новый процесс и его первичный поток, CreateProcess вернет TRUE.
Параметры и описание:
(1) pszApplicationName определяет имя исполняемого файла.
(2) pszCommandLine определяет командную строку, передаваемую этому процессу.
(3) psProcessAttr определяет атрибуты защиты для объекта «процесс». Если передается NULL, то значение по умолчанию (в этом случае дескриптор не может быть унаследован).
(4) psThreadAttr определяет атрибуты защиты для объекта «поток». Если передается NULL, то значение по умолчанию (в этом случае дескриптор не может быть унаследован).
(5) bInheritHandles определяет наследование дескрипторов. Если этот параметр равен TRUE, каждый наследуемый дескриптор в вызывающем процессе наследуется новым процессом. Если параметр FALSE, дескрипторы не наследуются. Обратите внимание, что унаследованные дескрипторы имеют то же значение и права доступа, что и исходные дескрипторы.
(6) fdwCreate определяет флаги, управляющие классом приоритета (6 шт.) и созданием процесса (13 шт.). Однако это необязательно и даже, как правило, не рекомендуется.
(7) pvEnvironment указывает на блок памяти, хранящий строки переменных окружения, которыми будет пользоваться новый процесс. Обычно вместо этого параметра передается NULL, в результате чего дочерний процесс наследует строки переменных окружения от родительского процесса.
(8) pszCurDir позволяет родительскому процессу установить текущие диск и каталог для дочернего процесса. Если его значение равно NULL, рабочий каталог нового процесса будет тем же, что и у приложения, его породившего.
(9) psiStartInfo указывает на структуру STARTUPINFO с 18-тью параметрами (разработчику данную структуру нужно создать и инициализировать перед вызовом функции).
(10) ppiProcInfo указывает на структуру PROCESS_INFORMATION, которую необходимо предварительно создать (разработчику нужно создать структуру, а инициализацией займется сама функция CreateProcess).
Возвращаемое значение.
Если функция завершается успешно, возвращаемое значение отлично от нуля (bool: true), иначе возвращаемое значение равно нулю (bool: false).
Пример (C++).
Программа открывает программу «Блокнот», ждёт 4 секунды, затем закрывает блокнот и завершается.
#include <iostream>
#include <windows.h>
using namespace std;
int main() {
STARTUPINFO cif;
/// Заполняет блок памяти нулями
ZeroMemory(&cif, sizeof(STARTUPINFO));
PROCESS_INFORMATION pi;
if (CreateProcess("C:\\Windows\\notepad.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &cif, &pi)) { /// Блокнот
/// Выводим Handle окна
cout << "Process handle " << pi.hProcess << endl;
Sleep(4000); /// Ждем 4 секунды
TerminateProcess(pi.hProcess, NO_ERROR); /// Закрываем блокнот
}
return 0;
}