Цель работы
Изучение способов работы с разделяемой памятью на основе
файлов, проецируемых в память. Изучение способов синхронизации процессов и
нитей с использованием мьютексов (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) и семафоров.
Комментариев нет:
Отправить комментарий