Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Обучение VC++ / ЛекцииИнтернетС++ / Лекция_лаб_практикум.doc
Скачиваний:
64
Добавлен:
16.02.2016
Размер:
932.35 Кб
Скачать

Пример 15. Использование событий.

Приложение использует событийный объект, чтобы предохранить несколько нитей от чтения разделенной памяти, в то время как основная нить пишет в этот буфер. Сначала основная нить, используя функцию CreateEvent создаёт массив событийных объектов. Она определяет событие, которое не возникает, когда основная нить пишет в разделяемую память, и возникает по окончании записи.Затем основная нить создаёт несколько читающих из разделяемой памяти нитей. Каждая нить-читатель устанавливает своё событие, чтобы сигнализировать когда она закончит читать из разделяемой памяти.

#include <vcl.h>

#include <stdio.h>

#pragma hdrstop

#pragma argsused

#define NUMTHREADS 4

void ThreadFunction(LPVOID lpParam);

void CreateEventsAndThreads(void);

void WriteToBuffer(void);

HANDLE hGlobalWriteEvent;

HANDLE hReadEvents[NUMTHREADS], hThread;

HANDLE hfilemap;

DWORD IDThread;

unsigned char *pwrite,i;

int main(int argc, char* argv[])

{

LPMSG msg;

CreateEventsAndThreads();

WriteToBuffer();

while (GetMessage(msg, NULL, 0, 0))

DispatchMessage(msg);

}

/* Создаёт событие, которое активизируется при окончании записи в память*/

void CreateEventsAndThreads(void){

hGlobalWriteEvent = CreateEvent(

NULL, // Security_Attributes

TRUE, // программный вызов события

TRUE, // статус инициализации события - активно

"WriteEvent" // имя объекта

);

if (hGlobalWriteEvent == NULL)

{GetLastError(); exit;}

/* Создаёт множество нитей и события для каждой с автосбросом.

Каждая нить устанавлмвает событие в активное, когда не читает из памяти

*/

for(i = 0; i < NUMTHREADS; i++)

{

// Создаёт массив автматических дезактивирующихся событий для читателей.

hReadEvents[i] = CreateEvent(

NULL, // Security_Attributes

FALSE, // автосброс события

TRUE, // статус инициализации события - активно

NULL); // неименованное событие

if (hReadEvents[i] == NULL)

{GetLastError(); exit;}

hThread = CreateThread(

NULL, // Security_Attributes

0, // Размер буфера

(LPTHREAD_START_ROUTINE) ThreadFunction, // Исполняемая функция

&hReadEvents[i], // Передача хендла события

0, // Флаги создания

&IDThread); // Идентификатор нити

if (hThread == NULL)

{GetLastError(); exit; }

}

}

VOID WriteToBuffer(VOID)

{

DWORD dwWaitResult, i;

// Сбрасывает событие hGlobalWriteEvent в неактивное, блокируя чтение.

if (!ResetEvent(hGlobalWriteEvent) )

{GetLastError(); exit;}

//Ожидает пока все нити закончат чтение.

dwWaitResult = WaitForMultipleObjects(

NUMTHREADS, // число хендлов в массиве событий читателей

hReadEvents, // массив хендлов событий читателей

TRUE, // ожидать пока все события не активизируются

INFINITE); // бесконечное ожидание

switch (dwWaitResult)

{

case WAIT_OBJECT_0:

printf(" /nMainthread: All read-event were signaled");

// Создаёт разделяемую память и пишет в неё 10 чисел

hfilemap=CreateFileMapping(NULL,NULL,PAGE_READWRITE,0,10,"shmem");

pwrite=(unsigned char *)MapViewOfFile(hfilemap,FILE_MAP_ALL_ACCESS,0,0,0);

printf("\n Mainthread write to share memory ");

for (i = 1; i<=10; i++)

{*pwrite=i; printf("%d ",*pwrite); pwrite++;}

break;

// An error occurred.

default:

printf("Wait error: %d\n", GetLastError());

ExitProcess(0);

}

// Устанавливает hGlobalWriteEvent в активное состояние.

if (! SetEvent(hGlobalWriteEvent) )

{GetLastError(); exit;}

// Set all read events to signaled.

for(i = 1; i <= NUMTHREADS; i++)

if (! SetEvent(hReadEvents[i]) )

{GetLastError(); exit;}

}

VOID ThreadFunction(LPVOID lpParam)

{

DWORD dwWaitResult;

HANDLE hEvents[2];

unsigned char *pread,i;

hEvents[0] = *(HANDLE*)lpParam; // нить читает хендл своего события

hEvents[1] = hGlobalWriteEvent; // событие на запись

dwWaitResult = WaitForMultipleObjects(

2, // число хендлов в массиве

hEvents, // массив хендловсобытий

TRUE, // ожидать пока все соьытия не активизируются

INFINITE); // бесконечное ожидание

switch (dwWaitResult)

{

// Оба события активны

case WAIT_OBJECT_0:

HANDLE hMapFile;

hMapFile = OpenFileMapping(FILE_MAP_READ, FALSE,"shmem");

pread=(unsigned char*)MapViewOfFile(

hMapFile, // Handle to mapping object.

FILE_MAP_ALL_ACCESS, // Read/write permission.

0, // Max. object size.

0, // Size of hFile.

0);

if (pread==NULL) // Map entire file.

{GetLastError();

ExitThread(0);}

printf("\nThread read from share memory \n");

for (i=1;i<=10;i++)

printf("%d ",*pread++);

break;

default:

printf("Wait error: %d\n", GetLastError());

ExitThread(0);

}

// Set the read event to signaled.

if (! SetEvent(hEvents[0]) )

{

// Error exit.

}

}