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

События

Читайте также:
  1. Монголо-татарское нашествие определило окончательное оформление регионов Киевской Руси. Назовите дату указанного события.
  2. Политические события 1917г. и становление новой государственности.ф
  3. Предшествующие события
  4. Принцип фиксации событий на «жесткие» и «мягкие» события и встречи.
  5. Состав противоборствующих сил и основные события “большой” гражданской войны
  6. Тема- идея- замысел- сюжетный ход- решение, подготовка репортажа с места события ( про карла маркса и Ленина)

События (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); };

 


1 | 2 | 3 | 4 | 5 | 6 |

Поиск по сайту:



Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.003 сек.)