Чтение онлайн

на главную

Жанры

Системное программирование в среде Windows

Харт Джонсон М.

Шрифт:

BOOL CreatePipe(PHANDLE phRead, PHANDLE phWrite, LPSECURITY_ATTRIBUTES lpsa, DWORD cbPipe)

Дескрипторы каналов часто бывают наследуемыми; причины этого станут понятными из приведенного ниже примера. Значение параметра cbPipe, указывающее размер канала в байтах, носит рекомендательный характер, причем значению 0 соответствует размер канала по умолчанию.

Чтобы канал можно было использовать для IPC, должен существовать еще один процесс, и для этого процесса требуется один из дескрипторов канала. Предположим, например, что родительскому процессу, вызвавшему функцию CreatePipe, необходимо

вывести данные, которые нужны дочернему процессу. Тогда возникает вопрос о том, как передать дочернему процессу дескриптор чтения (phRead). Родительский процесс осуществляет это, устанавливая дескриптор стандартного ввода в структуре STARTUPINFO для дочерней процедуры равным *phRead.

Чтение с использованием дескриптора чтения канала блокируется, если канал пуст. В противном случае в процессе чтения будет воспринято столько байтов, сколько имеется в канале, вплоть до количества, указанного при вызове функции ReadFile. Операция записи в заполненный канал, которая выполняется с использованием буфера в памяти, также будет блокирована.

Наконец, анонимные каналы обеспечивают только однонаправленное взаимодействие. Для двухстороннего взаимодействия необходимы два канала. 

Пример: перенаправление ввода/вывода с использованием анонимного канала

В программе 11.1 представлен родительский процесс, который создает два процесса из командной строки и соединяет их каналом. Родительский процесс устанавливает канал и осуществляет перенаправление стандартного ввода/вывода. Обратите внимание на то, каким образом задается свойство наследования дескрипторов анонимного канала и как организуется перенаправление стандартного ввода/вывода на два дочерних процесса; эти методики описаны в главе 6.

Местоположение оператора WriteFile в блоке Program2 на рис. 11.1 справа предполагает, что программа считывает большой объем данных, обрабатывает их, и лишь после этого записывает результаты. Эту запись можно было бы осуществлять и внутри цикла, выводя результаты после каждого считывания.

Рис. 11.1. Межпроцессное взаимодействие с использованием анонимного канала

Дескрипторы каналов и потоков должны закрываться при первой же возможности. На рис. 11.1 закрытие дескрипторов не отражено, однако это делается в программе 11.1. Родительский процесс должен закрыть дескриптор устройства стандартного вывода сразу же после создания первого дочернего процесса, чтобы второй процесс мог распознать метку конца файла, когда завершится выполнение первого процесса. В случае существования открытого дескриптора первого процесса второй процесс не смог бы завершиться, поскольку система не обозначила бы конец файла.

В программе 11.1 используется непривычный синтаксис: две команды, разделенные символом =, обозначающим канал. Использование для этой цели символа вертикальной черты (|) привело бы к возникновению конфликта с системным командным процессором. Рисунок 11.1 является схематическим представлением выполнения следующей команды:

$ pipe Program1 аргументы = Program2 аргументы

При использовании средств командного процессора UNIX или Windows соответствующая команда имела бы следующий вид:

$ Program1 аргументы | Program2 аргументы

Программа 11.1. pipe:
межпроцессное взаимодействие с использованием анонимных каналов 

#include "EvryThng.h"

int _tmain(int argc, LPTSTR argv[])

/* Соединение двух команд с помощью канала в командной строке: pipe команда1 = команда2 */

{

 DWORD i = 0;

 HANDLE hReadPipe, hWritePipe;

 TCHAR Command1[MAX_PATH];

 SECURITY_ATTRIBUTES PipeSA = /* Для наследуемых дескрипторов. */

{sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};

 PROCESS_INFORMATION ProcInfo1, ProcInfo2;

 STARTUPINFO StartInfoCh1, StartInfoCh2;

 LPTSTR targv = SkipArg(GetCommandLine);

 GetStartupInfo(&StartInfoCh1);

 GetStartupInfo(&StartInfoCh2);

 /* Найти символ "=", разделяющий две команды. */

 while (*targv != '=' && *targv != '\0') {

Command1[i] = *targv;

targv++;

i++;

 }

 Command1[i] = '\0';

 /* Пропуск до начала второй команды. */

 targv = SkipArg(targv);

 CreatePipe(&hReadPipe, &hWritePipe, &PipeSA, 0);

 /* Перенаправить стандартный вывод и создать первый процесс. */

 StartInfoCh1.hStdInput = GetStdHandle(STD_INPUT_HANDLE);

 StartInfoCh1.hStdError = GetStdHandle(STD_ERROR_HANDLE);

 StartInfoCh1.hStdOutput = hWritePipe;

 StartInfoCh1.dwFlags = STARTF_USESTDHANDLES;

 CreateProcess(NULL, (LPTSTR)Command1, NULL, NULL, TRUE /* Унаследовать дескрипторы. */, 0, NULL, NULL, &StartInfoCh1, &ProcInfo1);

 CloseHandle(ProcInfo1.hThread);

 /* Закрыть дескриптор записи канала, поскольку он больше не нужен, чтобы вторая команда могла обнаружить конец файла. */

 CloseHandle(hWritePipe);

 /* Повторить операции (симметричным образом) для второго процесса. */

 StartInfoCh2.hStdInput = hReadPipe;

 StartInfoCh2.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);

 StartInfoCh2.hStdError = GetStdHandle(STD_ERROR_HANDLE);

 StartInfoCh2.dwFlags = STARTF_USESTDHANDLES;

 CreateProcess(NULL, (LPTSTR)targv, NULL, NULL, TRUE, 0, NULL, NULL, &StartInfoCh2, &ProcInfo2);

Поделиться:
Популярные книги

Предатель. Цена ошибки

Кучер Ая
Измена
Любовные романы:
современные любовные романы
5.75
рейтинг книги
Предатель. Цена ошибки

Вечный. Книга V

Рокотов Алексей
5. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга V

Мимик нового Мира 13

Северный Лис
12. Мимик!
Фантастика:
боевая фантастика
юмористическая фантастика
рпг
5.00
рейтинг книги
Мимик нового Мира 13

Идеальный мир для Лекаря 15

Сапфир Олег
15. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 15

Чужой ребенок

Зайцева Мария
1. Чужие люди
Любовные романы:
современные любовные романы
6.25
рейтинг книги
Чужой ребенок

Новый Рал 3

Северный Лис
3. Рал!
Фантастика:
попаданцы
5.88
рейтинг книги
Новый Рал 3

Кодекс Охотника. Книга XV

Винокуров Юрий
15. Кодекс Охотника
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XV

Возвышение Меркурия. Книга 12

Кронос Александр
12. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 12

Провинциал. Книга 5

Лопарев Игорь Викторович
5. Провинциал
Фантастика:
космическая фантастика
рпг
аниме
5.00
рейтинг книги
Провинциал. Книга 5

Польская партия

Ланцов Михаил Алексеевич
3. Фрунзе
Фантастика:
попаданцы
альтернативная история
5.25
рейтинг книги
Польская партия

Бальмануг. (Не) Любовница 1

Лашина Полина
3. Мир Десяти
Фантастика:
юмористическое фэнтези
попаданцы
5.00
рейтинг книги
Бальмануг. (Не) Любовница 1

Чиновникъ Особых поручений

Кулаков Алексей Иванович
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чиновникъ Особых поручений

Последний попаданец 2

Зубов Константин
2. Последний попаданец
Фантастика:
юмористическая фантастика
попаданцы
рпг
7.50
рейтинг книги
Последний попаданец 2

Черный Маг Императора 7 (CИ)

Герда Александр
7. Черный маг императора
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Черный Маг Императора 7 (CИ)