Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Работа с объектами событий




 

Объект события используется для оповещения процесса или потока о том, что произошло некоторое событие. Для работы с такими объектами предназначен класс CEvent. Конструктор класса имеет следующий прототип:

 

CEvent(BOOL bInitiallyOwn = FALSE, BOOL bManualReset = FALSE, LPCTSTR lpszName = NULL, LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);

Значение первого параметра определяет начальное состояние объекта. Если оно равно TRUE, то объект события установлен (событие произошло), а если FALSE, то объект не установлен или сброшен (событие не произошло).

Второй параметр указывает, каким образом состояние объекта будет изменяться при выполнении события. Если значение параметра равно TRUE (не ноль), то объект может быть сброшен только путем вызова метода ResetEvent класса CEvent. В противном случае объект автоматически сбрасывается после предоставления блокированному потоку доступа к ресурсу.

Третий параметр конструктора указывает на строку, содержащую имя объекта события. Поименованные объекты события становятся системными объектами и могут использоваться другими процессами. Вместо имени строки можно указать NULL - в этом случае объект события будет локализован внутри одного процесса.

Последний параметр конструктора является указателем на набор атрибутов прав доступа, связанный с объектом события. Если этот параметр равен NULL, то объект события наследует данный набор у вызвавшего его потока.

Когда объект события создан, то поток, ожидающий данное событие, должен создать объект класса CSingleLock, для которого затем следует вызвать метод Lock. При этом выполнение данного потока останавливается до тех пор, пока не произойдет ожидаемое событие. Для сигнализации о том, что событие произошло, предназначена функция SetEvent класса CEvent. Она переводит объект события в состояние «сигнализирует». При этом поток, ожидающий событие, выйдет из остановленного состояния (вызванный им метод Lock завершится) и выполнение потока продолжится.

Чтобы продемонстрировать работу с объектами события, дополним наше приложение следующими функциями. Создадим два пункта меню: «Start Thread 2» и «End Thread 2». По пункту «Start Thread 2» должен запускаться процесс MyThread2, по пункту «End Thread 2» должен заканчиваться процесс MyThread2 с выдачей сообщения "MyThread2 ended". Если запуск процесса легко осуществить с помощью объекта события, то завершение процесса легче реализовать с помощью глобальной переменной.

Всем потокам процесса доступны все глобальные переменные процесса. Но может возникнуть ситуация, когда выполнение потока прерывается в тот момент, когда значение глобальной переменной является некорректным. Значение переменной может загружаться в регистр для выполнения некоторых операций. Если прерывание наступит в момент, когда значение переменной находится в регистре, а второй поток изменит ее значение в памяти, первый поток испортит ее значение, возвращая из регистра соответствующее значение. Одним из способов решения такой проблемы является объявление переменной как volatile, что гарантирует, что она не будет размещаться компилятором в регистре.

Выполните следующие действия для реализации объекта события и использования глобальной переменной.

1. С помощью редактора ресурсов добавьте команды Start Thread 2 и End Thread 2 в меню Thread приложения. Присвойте этим командам идентификаторы ID_STARTTHREAD2 и ID_ENDTHREAD2.

2. С помощью СlassWizard свяжите команду ID_STARTTHREAD2 с функцией обработки сообщения OnStartthread2(), команду ID_ENDTHREAD2 с функцией обработки сообщения OnEndhread2(). Перед тем как добавить новую функцию, убедитесь, что в поле Class Name выбрано значение CExampleView.

3. Добавьте в начало файла ExampleView.cpp приведенную ниже строку, поместив ее сразу после строки #include "SomeResource.h":

 

#include "afxmt.h"

 

Этот оператор подключает заголовочный файл для работы с классами объектов синхронизации.

4. Включите в начало файла ExampleView.cpp, сразу же после объявления

 

CSomeResource someResource

 

следующую строку:

 

volatile bool keeprunning;

 

5. Добавьте в начало файла ExampleView.cpp приведенные ниже строки, поместив их после строки volatile bool keeprunning;:

 

CEvent threadStart;

CEvent threadEnd;

 

6. Добавьте в функцию UINT MyThread2(LPVOID pParam) в файле ExampleView.cpp строки

 

CSingleLock syncObjStart(&threadStart);

syncObjStart.Lock();

 

перед циклом for. Первая функция создает объект syncObjStart класса CSingleLock для объекта события threadStart. Это вызов конструктора.

Вторая функция вызывает метод Lock() для этого объекта. Выполнение данного потока останавливается до тех пор, пока не произойдет событие для этого объекта.

7. Добавьте в функцию UINT MyThread2(LPVOID pParam) в файле ExampleView.cpp в теле цикла после строки

 

MessageBeep(0);

 

строки

 

if (keeprunning==FALSE){

AfxMessageBox("MyThread2 ended");

break;}

 

Теперь при каждом проходе цикла будет осуществляться проверка глобальной переменной, и если она станет равна FALSE, цикл прервется и поток завершит свою работу.

8. Добавьте в функцию void CExampleView::OnStartthread2() строки:

 

keeprunning=TRUE;//начальное значение переменной keeprunning

threadStart.SetEvent();//объект события в состояние «сигнализирует» (событие произошло).

После ее выполнения метод Lock(), который ждет этого события, завершает свою работу, и выполняются следующие функции.

9. Добавьте в функцию void CExampleView::OnEndthread2() строку:

 

keeprunning=FALSE;

 

Теперь очередной цикл в функции MyThread2 прервется, и поток завершит свою работу.

 




Поделиться с друзьями:


Дата добавления: 2014-11-29; Просмотров: 389; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.018 сек.