// Программа из конспекта "Системное программное обеспечение" // Файлы, отображаемые на память, синхронизация событиями // стр. ?? // Приложение MFE_CLIENT (клиентское приложение) // Демонстрация использования файлов, отображаемых на память, // для передачи данных между процессами, синхронизированными событиями (Events) #define _CRT_SECURE_NO_WARNINGS #include #include #include #include // Идентификаторы объектов-событий, которые используются // для синхронизации задач, принадлежащих разным процессам HANDLE hEventSend; HANDLE hEventRecv; HANDLE hEventTermination; // Имя объектов-событий для синхронизации записи и чтения из отображаемого файла CHAR lpEventSendName[] = "$MylEventSendName$"; CHAR lpEventRecvName[] = "$MylEventRecvName$"; // Имя объекта-события для завершения процесса CHAR lpEventTerminationName[] = "$MyEventTerminationName$"; // Имя отображния файла на память CHAR lpFileShareName[] = "$MyFileShareName$"; // Идентификатор отображения файла на память HANDLE hFileMapping; // Указатель на отображенную область памяти LPVOID lpFileMap; int main() { CHAR str[80]; DWORD dwRetCode; printf("Mapped and shared file, event sync, client process\n" "\n\nEnter to terminate...\n"); // Открываем объекты-события для синхронизации // чтения и записи hEventSend = OpenEvent(EVENT_ALL_ACCESS, FALSE, lpEventSendName); hEventRecv = OpenEvent(EVENT_ALL_ACCESS, FALSE, lpEventRecvName); if (hEventSend == NULL || hEventRecv == NULL) { fprintf(stdout, "OpenEvent: Error %ld\n", GetLastError()); _getch(); return 0; } // Открываем объект-событие для сигнализации о // завершении процесса hEventTermination = OpenEvent(EVENT_ALL_ACCESS, FALSE, lpEventTerminationName); if (hEventTermination == NULL) { fprintf(stdout, "OpenEvent (Termination): Error %ld\n", GetLastError()); _getch(); return 0; } // Открываем объект-отображение hFileMapping = OpenFileMapping( FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileShareName); // Если открыть не удалось, выводим код ошибки if (hFileMapping == NULL) { fprintf(stdout, "OpenFileMapping: Error %ld\n", GetLastError()); _getch(); return 0; } // Выполняем отображение файла на память. // В переменную lpFileMap будет записан указатель на // отображаемую область памяти lpFileMap = MapViewOfFile(hFileMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); // Если выполнить отображение не удалось, // выводим код ошибки if (lpFileMap == 0) { fprintf(stdout, "MapViewOfFile: Error %ld\n", GetLastError()); _getch(); return 0; } // Цикл чтения/записи данных. Этот цикл завершает свою работу, // когда пользователь набирает коанду , while (TRUE) { // Читаем введенную строку gets_s(str); // Записываем строку в отображенную память, // доступную серверному процессу strcpy((char*)lpFileMap, str); // Если введена команда , прерываем цикл if (!strcmp(str, "exit") || !strcmp(str, "Exit") || !strcmp(str, "EXIT")) break; // Записываем строку в отображенную память, // доступную серверному процессу strcpy((char*)lpFileMap, str); // Устанавливаем объект-событие в отмеченное // состояние SetEvent(hEventSend); // ждем ответа dwRetCode = WaitForSingleObject(hEventRecv, INFINITE); // если ответ получен - выводим, если ошибка - выходим if (dwRetCode == WAIT_OBJECT_0) puts(((LPSTR)lpFileMap)); if (dwRetCode == WAIT_ABANDONED_0 || dwRetCode == WAIT_FAILED) { printf("\nError waiting responce!\n)"); //break; } } // После завершения цикла переключаем все события // в отмеченное состояние для отмены ожидания в // процессе отображения и для завершения этого процесса //SetEvent(hEventSend); SetEvent(hEventTermination); // Закрываем идентификаторы объектов-событий CloseHandle(hEventSend); CloseHandle(hEventRecv); CloseHandle(hEventTermination); // Отменяем отображение файла UnmapViewOfFile(lpFileMap); // Освобождаем идентификатор созданного // объекта-отображения CloseHandle(hFileMapping); return 0; }