- •Глава 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 CallNamedPipe(
LPCSTR lpNamedPipeName,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesRead,
DWORD nTimeOut,
);
Параметры и описание:
(1) lpNamedPipeName — определяет название именованного канала.
(2) lpInBuffer — определяет данные для записи в канал.
(3) nInBufferSize — определяет размер буфера записи в байтах.
(4) lpOutBuffer — определяет указатель на буфер, который получает данные, прочитанные из канала.
(5) nOutBufferSize — определяет размер буфера чтения в байтах.
(6) lpBytesRead — определяет указатель на переменную, которая получает количество байтов, прочитанных из канала.
(7) nTimeOut — определяет количество миллисекунд ожидания для того, чтобы именованный канал был доступен. В дополнение к числовым значениям могут быть указаны следующие специальные значения.
— NMPWAIT_NOWAIT (0x00000001) — не ждет именованного канала. Если именованный канал недоступен, функция возвращает ошибку.
— NMPWAIT_WAIT_FOREVER (0xffffffff) — ждет бесконечно.
— NMPWAIT_USE_DEFAULT_WAIT (0x00000000) — используется время ожидания по умолчанию, указанное при вызове функции CreateNamedPipe.
Возвращаемое значение.
Если функция завершается успешно, возвращаемое значение равно TRUE, иначе FALSE.
Если сообщение, записанное в канал серверным процессом, длиннее, чем nOutBufferSize, CallNamedPipe возвращает FALSE, а GetLastError возвращает ERROR_MORE_DATA. Оставшаяся часть сообщения отбрасывается, потому что CallNamedPipe закрывает дескриптор канала перед возвратом.
Дополнительная информация.
Вызов CallNamedPipe эквивалентен вызову функций CreateFile (или WaitNamedPipe, если CreateFile не может сразу открыть канал), TransactNamedPipe и CloseHandle. CreateFile вызывается с флагом доступа GENERIC_READ | GENERIC_WRITE и флаг дескриптора наследования FALSE.
Пример (C).
CLIENT
#include <windows.h>
int main() {
HANDLE hPipe;
DWORD dwWritten;
hPipe = CreateFile(TEXT("\\\\.\\pipe\\Pipe"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hPipe != INVALID_HANDLE_VALUE) {
WriteFile(hPipe, "Hello Pipe\n", 12, &dwWritten, NULL);
CloseHandle(hPipe);
}
return 0;
}
SERVER
#include <stdio.h>
#include <windows.h>
int main() {
HANDLE hPipe;
char buffer[1024];
DWORD dwRead;
hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Pipe"), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024 * 16, 1024 * 16, NMPWAIT_USE_DEFAULT_WAIT, NULL);
while (hPipe != INVALID_HANDLE_VALUE) {
if (ConnectNamedPipe(hPipe, NULL) != FALSE) {
while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) != FALSE) {
buffer[dwRead] = '\0';
printf("%s", buffer);
}
}
DisconnectNamedPipe(hPipe);
}
return 0;
}