Студопедия
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

События

Читайте также:
  1. В15. Расположите следующие события в хронологической последовательности. Запишите буквы, которыми обозначены события, в правильной последовательности.
  2. Великая Отечественная война: основные этапы, события. Хронология событий.
  3. Вероятность случайного события
  4. Внешняя политика России во второй половине XIX в. События на Балканах и в Средней Азии.
  5. Вопрос№24. Каковы причины революции 1905 года? Опишите ее ход и основные события.
  6. Г. в России: основные события, их характер и значение.
  7. Г. в России: Основные события, характер и значение революционных потрясений в стране.
  8. Год в России (основные события, их характер и значение). (Билет 7)
  9. Год в России: основные события, их характер и значение. Гражданская война в России (1918–1920 гг.): причины, участники, этапы, итоги.
  10. Даты, события и персоналии по теме

События (Event), также как и мьютексы имеют два состояния - установленное и сброшенное. События бывают со сбросом вручную и с автосбросом. Когда поток дождался (wait-функция вернула управление) события с автосбросом, такое событие автоматически сбрасывается. В противном случае событие нужно сбрасывать вручную, вызвав функцию ResetEvent(). Допустим, сразу несколько потоков ожидают одного и того же события, и событие сработало. Если это было событие с автосбросом, то оно позволит работать только одному потоку (ведь сразу же после возврата из его wait-функции событие сбросится автоматически!), а остальные потоки останутся ждать. Если же это было событие со сбросом вручную, то все потоки получат управление, а событие так и останется в установленном состоянии, пока какой-нибудь поток не вызовет ResetEvent().

Пример 5. Вот еще один пример многопоточного приложения. Программа имеет два потока; один готовит данные, а второй отсылает их на сервер. Разумно распараллелить их работу. Здесь потоки должны работать по очереди. Сначала первый поток готовит порцию данных. Потом второй поток отправляет ее, а первый тем временем готовит следующую порцию и т.д. Для такой синхронизации понадобится два event'а с автосбросом.

 

unsigned __stdcall CaptureThreadFunc(void * arg) // Поток, готовящий данные { while (bSomeCondition) { WaitForSingleObject(m_hEventForCaptureTh,INFINITE); // Ждем своего события... // Готовим данные SetEvent(hEventForTransmitTh); // Разрешаем работать второму потоку } _endthreadex(0); return 0; }; unsigned __stdcall TransmitThreadFunc(void * arg) // Поток, отсылающий данные. { while (bSomeCondition) { WaitForSingleObject(m_hEventForTransmitTh,INFINITE); // Ждем своего события... // Данные готовы, формируем из них пакет для отправки SetEvent(hEventForCaptureTh); // Разрешаем работать первому потоку, а сами...... // отправляем пакет } _endthreadex(0); return 0; }; int main(int argc, char* argv[]) // Основной поток { // Создаем два события с автосбросом, со сброшенным начальным состоянием hEventForCaptureTh = CreateEvent(NULL,FALSE,FALSE,NULL); hEventForTransmitTh = CreateEvent(NULL,FALSE,FALSE,NULL); // Создаем потоки hCaptureTh = (HANDLE)_beginthreadex(NULL, 0, &CaptureThreadFunc, 0, 0,&uTh1); hTransmitTh = (HANDLE)_beginthreadex(NULL, 0, &TransmitThreadFunc, 0, 0,&uTh2); // Запускаем первый поток SetEvent(hEventForCaptureTh);.... }

 

Пример 6. Другой пример. Программа непрерывно в цикле производит какие-то вычисления. Нужно иметь возможность приостановить на время ее работу. Допустим, это просмотрщик видео файлов, который в цикле, кадр за кадром отображает информацию на экран. Не будем вдаваться в подробности видео функций. Реализуем функции Pause и Play для программы. Используем событие со сбросом вручную.

 

// Главная функция потока, которая в цикле отображает кадры unsigned __stdcall VideoThreadFunc(void * arg) { while (bSomeCondition) { WaitForSingleObject(m_hPauseEvent,INFINITE); // Если событие сброшено, ждем... // Отображаем очередной кадр на экран } _endthreadex(0); return 0; }; void Play() { SetEvent(m_hPauseEvent); }; void Pause() { ResetEvent(m_hPauseEvent); };

Функция PulseEvent() устанавливает событие и тут же переводит его обратно в сброшенное состояние; ее вызов равнозначен последовательному вызову SetEvent() и ResetEvent(). Если PulseEvent вызывается для события со сбросом в ручную, то все потоки, ожидающие этот объект, получают управление. При вызове PulseEvent для события с автосбросом пробуждается только один из ждущих потоков. А если ни один из потоков не ждет объект-событие, вызов функции не дает никакого эффекта.

Пример 7. Реализуем функцию NextFrame() для предыдущего примера для промотки файла вручную по кадрам.

 

void NextFrame() { PulseEvent(m_hPauseEvent); };

 




Дата добавления: 2015-04-26; просмотров: 96 | Поможем написать вашу работу | Нарушение авторских прав

1 | 2 | 3 | <== 4 ==> | 5 | 6 |


lektsii.net - Лекции.Нет - 2014-2025 год. (0.164 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав