/// Программа из конспекта "Системное программное обеспечение" // Файлы, отображаемые на память, синхронизация мьютексами // стр. ?? // Приложение MFM_CLIENT (клиентское приложение) // Демонстрация использования файлов, отображаемых на память, // для передачи данных между процессами, синхронизированными мьютексами (Mutex) #define _CRT_SECURE_NO_WARNINGS #include #include #include #include // Идентификаторы объектов-событий, которые используются // для синхронизации задач, принадлежащих разным процессам HANDLE hMutexSend; HANDLE hMutexRecv; HANDLE hMutexTermination; // Имя объектов-событий для синхронизации записи и чтения из отображаемого файла CHAR lpMutexSendName[] = "$MyMutexSendName$"; CHAR lpMutexRecvName[] = "$MyMutexRecvName$"; // Имя объекта-события для завершения процесса CHAR lpMutexTerminationName[] = "$MyMutexTerminationName$"; // Имя отображния файла на память CHAR lpFileShareName[] = "$MyFileShareName$"; // Идентификатор отображения файла на память HANDLE hFileMapping; // Указатель на отображенную область памяти LPVOID lpFileMap; int main() { CHAR str[80]; DWORD dwRetCode; printf("Mapped and shared file, mutex sync, client process\n" "\n\nEnter to terminate...\n"); // Открываем объект-мьютекс для синхронизации чтения/записи hMutexRecv = OpenMutex(MUTEX_ALL_ACCESS, FALSE, lpMutexRecvName); hMutexSend = OpenMutex(MUTEX_ALL_ACCESS, FALSE, lpMutexSendName); if (hMutexRecv == NULL || hMutexSend == NULL) { fprintf(stdout, "OpenMutex %s: Error %ld\n", lpMutexRecvName, GetLastError()); _getch(); return 0; } // Создаем объект-мьютексы для сигнализации о завершении процесса hMutexTermination = CreateMutex(0, TRUE, lpMutexTerminationName); if (hMutexTermination == NULL) { fprintf(stdout, "CreateMutex (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) { // Устанавливаем объект-мьютекс в захваченное состояние dwRetCode = WaitForSingleObject(hMutexSend, INFINITE); // Читаем введенную строку gets_s(str); // Записываем строку в отображенную память, // доступную серверному процессу strcpy((char*)lpFileMap, str); // Отпускаем объект-мьютекс ReleaseMutex(hMutexSend); // Если введена команда , прерываем цикл if (!strcmp(str, "exit") || !strcmp(str, "Exit") || !strcmp(str, "EXIT")) break; // ждем ответа dwRetCode = WaitForSingleObject(hMutexRecv, INFINITE); // если ответ получен - выводим, если ошибка - выходим if (dwRetCode == WAIT_OBJECT_0) puts(((LPSTR)lpFileMap)); if (dwRetCode == WAIT_ABANDONED_0 || dwRetCode == WAIT_FAILED) { printf("\nError waiting responce!\n)"); break; } ReleaseMutex(hMutexRecv); } // После завершения цикла переключаем все мьютексы // в отмеченное состояние для отмены ожидания в // процессе отображения и для завершения этого процесса ReleaseMutex(hMutexSend); ReleaseMutex(hMutexTermination); // Закрываем идентификаторы объектов-событий CloseHandle(hMutexSend); CloseHandle(hMutexRecv); CloseHandle(hMutexTermination); // Отменяем отображение файла UnmapViewOfFile(lpFileMap); // Освобождаем идентификатор созданного // объекта-отображения CloseHandle(hFileMapping); return 0; }