Лабораторная работа: Работа с разделяемой памятью

Цель работы

Изучение способов работы с разделяемой памятью на основе файлов, проецируемых в память. Изучение способов синхронизации процессов и нитей с использованием мьютексов (mutex) и семафоров.

Список используемых системных вызовов

CreateFileMapping, OpenFileMapping, MapViewOfFile, UnmapViewOfFile, CloseHandle, CreateMutex, OpenMutex, CreateSemaphore, OpenSemaphore, ReleaseMutex, ReleaseSemaphore, WaitForSingleObject, WaitForMultipleObjects.

Методические указания

Для получения разделяемой памяти необходимо создать файл, проецируемый в память не на диске, а в свопинге системы, с помощью функции CreateFileMapping. Это достигается заданием в первом параметре hFile значения INVALID_HANDLE_VALUE. Проекция файла на адресное пространство процесса задается с помощью функций MapViewOfFile или MapViewOfFileEx. По окончании работы следует вызвать функции UnmapViewOfFile и CloseHandle для дескриптора спроецированного в память файла.
Мьютексы и семафоры позволяют синхронизировать нити в разных процессах (как и события), поскольку являются объектами операционной системы. Мьютекс, по сути, является упрощенной формой семафора. Принципиальным отличием мьютекса от семафора является возможность повторного занятия мьютекса одной и той же нитью.
Мьютексы и семафоры порождаются с помощью функций CreateMutex и CreateSemaphore. Для занятия мьютекса или семафора используется любая из группы WaitFor-функций. Для освобождения объектов используются соответственно функции ReleaseMutex и ReleaseSemaphore.

Задания

         11.    Разработать систему из двух программ. Первая программа предназначена для ввода команд DOS. Вторая программа демонстрирует результаты выполнения команд. Синхронизация с использованием семафоров.

                                                           Листинг программы.
Первая программа:
#include <stdio.h>
#include <windows.h>

void main()
{
            //данная программа предназначена для ввода команд ДОС
            //команды будут передаваться в другую программа через разделяемую память
            //синхронизация на основе семафоров
            HANDLE hSem, hFileMap;
            LPVOID lpMapAddress;
            int i=0;
            char cmd[256];

            //создадим семафор
            hSem = CreateSemaphore(NULL,1,1,"mysem");
            if(hSem ==NULL)
            {
                        printf("\nCould not create semaphore!!!");
                        exit(0);
            }

            hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,100,"filemap");
            if (hFileMap == NULL)
            {
                        printf("\nCould not create file mapping object!!!");
                        exit(0);
            }

            lpMapAddress = MapViewOfFile(hFileMap,FILE_MAP_WRITE,0,0,0);
            if (lpMapAddress == NULL)
            {
                        printf("\nCould not map view of file!!!");
                        exit(0);
            }
            //семафор установлен в 0 - память наша, пишем в нее команду ДОС
            while(1)
            {
                        /*** команда дос ***/
                        WaitForSingleObject(hSem,INFINITE);
                        cmd[0]=NULL;
                        printf("\nInput DOS command(exit to quit): ");
                        scanf("%s",&cmd);
                       
                        //пишем команду в разделяемую память
                       
                        memcpy( lpMapAddress, cmd, 256);
                        if(!FlushViewOfFile(lpMapAddress, sizeof(cmd)))
                        {
                                   printf("\nError write shared memory!!!");
                                   exit(0);
                        }
                        //освобождаем семафор
                        ReleaseSemaphore(hSem,1,NULL);
           
                        if(strcmp(cmd,"exit")==0)break;

            }

            UnmapViewOfFile(lpMapAddress) ;
            CloseHandle(hFileMap);       
            CloseHandle(hSem);

}

Вторая программа:
#include <stdio.h>
#include <windows.h>
#include <shellapi.h>
#include <ostream.h>

void main()
{
            //данная программа предназначена для чтение команд ДОС из разделяемой памяти
            //синхронизация на основе семафоров
            HANDLE hSem, hFileMap;
            LPVOID lpMapAddress;
            char cmd[256];
            //создадим семафор
            hSem = OpenSemaphore(SEMAPHORE_ALL_ACCESS ,FALSE,"mysem");
            if(hSem ==NULL)
            {
                        printf("\nCould not create semaphore!!!");
                        exit(0);
            }

            hFileMap = OpenFileMapping(FILE_MAP_READ,FALSE,"filemap");
            if (hFileMap == NULL)
            {
                        printf("\nCould not create file mapping object!!!");
                        exit(0);
            }

            lpMapAddress = MapViewOfFile(hFileMap,FILE_MAP_READ,0,0,0);
            if (lpMapAddress == NULL)
            {
                        printf("\nCould not map view of file!!!");
                        exit(0);
            }
            //семафор установлен в 0 - память наша, пишем в нее команду ДОС
            while(1)
            {
                        /*** команда дос ***/
                        //ожидаем освобождения семафора
                        WaitForSingleObject(hSem,INFINITE);
                        cmd[0]=NULL;
                        //читаем команду из разделяемой памяти.
                        memcpy( cmd,lpMapAddress,256);
                        printf("\n %s \n",cmd);
                        //освобождаем семафор
                        ReleaseSemaphore(hSem,1,NULL);
                        if(strcmp(cmd,"exit")==0)break;
                        WinExec(cmd,SW_SHOW);

            }

            UnmapViewOfFile(lpMapAddress) ;
            CloseHandle(hFileMap);       
            CloseHandle(hSem);

}

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

Комментариев нет:

Отправить комментарий