КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Неименованные каналы в Windows
Для создания неименованных каналов в Windows NT (и Windows 9x) предназначена системная функция CreatePipe, имеющая прототип BOOL CreatePipe(HANDLE* phReadPipe, HANDLE* phWritePipe, LPSECURITY_ATTRIBUTES pAttributes, DWORD nSize), где phReadPipe – адрес переменной для хэндла чтения из канала, phWritePipe – адрес переменной для хэндла записи в канал, pAttributes – адрес атрибутов защиты, nSize – число байтов, резервируемых для канала. Для манипуляций с хэндлами стандартного ввода и вывода в Windows можно использовать не только универсальную функцию DuplicateHandle копирования хэндлов (которая здесь предназначена для копирования хэндлов любых объектов ядра, а не только файлов), но и более простую специализированную функцию SetStdHandle. Она позволяет построить строку таблицы соответствия для стандартного ввода или вывода в строке таблицы соответствия, явно указываемой номером хэндла. Эта функция имеет прототип BOOL SetStdHandle(DWORD nStdHandle, HANDLE hHandle), где nStdHandle – условное обозначение хэндла стандартного ввода, вывода или ошибок, задаваемое одной из символических констант STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE. Аргумент hHandle задает хэндл для той строки таблицы соответствия, на место которой копируется строка таблицы соответствия для хэндла стандартного ввода или вывода. В листингах 11.3.1 и 11.3.2 приведены программы родительского и дочернего процессов, которые демонстрируют использование неименованных каналов в Windows.
#include <stdio.h> #include <windows.h> #define PIPESIZE 16 int main() {HANDLE hW, hR, hstdout; DWORD rc, cbRead; STARTUPINFO si; PROCESS_INFORMATION pi; DWORD CreationFlags; char bufread[PIPESIZE]="-";
hstdout = GetStdHandle(STD_OUTPUT_HANDLE); if(!CreatePipe(&hR, &hW, NULL, PIPESIZE)) {printf("Error create Pipe\n");getchar();exit(1);}; SetStdHandle(STD_OUTPUT_HANDLE, hW);
memset(&si, 0, sizeof(STARTUPINFO)); si.cb=sizeof(si); CreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; rc=CreateProcess(NULL, "childpip.exe", NULL, NULL, TRUE, //наследуемые CreationFlags, NULL, NULL, &si, &pi); if (!rc) {printf("Error create Process, codeError = %ld\n", GetLastError()); getchar(); return 0; } CloseHandle(hW); do {rc=ReadFile(hR, bufread, 4, &cbRead, NULL); if (!rc) {rc=GetLastError(); if (rc= =ERROR_BROKEN_PIPE) break; else {printf("Error ReadFile, rc=%d\n", rc); } } Sleep(1000); WriteFile(hstdout, bufread,cbRead,&cbRead,NULL); } while (cbRead!=0); printf("\nEnd work with pipe\n"); CloseHandle(hstdout); CloseHandle(hR); return 0; } Листинг 11.3.1. Программа родительского процесса
#include <stdio.h> #include <windows.h>
int main() {int step=0; DWORD cb; int portion=9; char text[ ]="У лукоморья дуб зеленый, златая цепь на дубе том."; char *ptxt=text, *textend=text+sizeof(text)-2; HANDLE hstdout; hstdout = GetStdHandle(STD_OUTPUT_HANDLE); ptxt=text; while(ptxt<=textend) {if (ptxt>textend-portion) portion=textend-ptxt+1; //last portion may be less than 9 fprintf(stderr,"----I am Child... (step=%d)\n\r", ++step); WriteFile(hstdout, ptxt, portion,&cb, NULL); ptxt+=portion; Sleep(2000); } CloseHandle(hstdout); return 0; } Листинг 11.3.2. Программа childpip.exe дочернего процесса
Получение данных через канал в Windows имеет свои особенности. Попытка чтения данных из канала, передающий конец в котором закрыт, приводит не к нулевому числу прочитанных байтов, а к возвращаемому функцией ReadFile значению FALSE. Тем самым как бы фиксируется ошибка. При этом функция GetLastError() возвращает значение символической константы ERROR_BROKEN_PIPE (равное 109). Нормально построенная программа чтения данных из канала должна распознавать это значение как обычное завершение данных в канале аналогично концу файла. Именно так построена программа последнего примера. Заметим, что в программе родительского процесса при создании дочернего процесса использован параметр наследования (пятый аргумент функции CreateProcess), равный TRUE. Это значение заставляет дочерний процесс унаследовать все дескрипторы открытых объектов и соответственно хэндлы этих дескрипторов.
Дата добавления: 2014-01-05; Просмотров: 1221; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |