Класс CEvent

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

class CEvent : public CSyncObject

Члены

Открытые конструкторы

Имя

Описание

CEvent::CEvent

Создает объект CEvent.

Открытые методы

Имя

Описание

CEvent::PulseEvent

Устанавливает событие в сигнальное доступному (), потоки в состоянии ожидания выпусков и наборам событие к отсутствующему (nonsignaled).

CEvent::ResetEvent

Устанавливает событие к отсутствующему (nonsignaled).

CEvent::SetEvent

Устанавливает событие в сигнальное доступные выпуски () и всех потоков в состоянии ожидания.

CEvent::Unlock

Освобождает объект события.

Заметки

События полезны, когда поток должен знать, когда для выполнения задачи. Например, поток, в котором данные копируются в архив данных следует уведомить, когда новые данные недоступны. С помощью объекта CEvent для уведомления копия поток, когда новые данные доступны, поток может выполнить свою задачу как можно скорее.

Объекты CEvent имеют 2 типа: ручной, так и автоматический.

Авто автоматически возвращает объект CEvent в сигнальное состояние (), не относящихся к отсутствующему после того как минимум один поток будет освобожден. По умолчанию объект CEvent автоматическое если не передавая TRUE для параметра bManualReset во время разработки.

Объект CEvent руководства остается в состоянии установленного SetEvent или ResetEvent до тех пор, пока другая функция не называется. Чтобы создать объект CEvent, передайте TRUE для параметра bManualReset во время разработки.

Чтобы использовать объект CEvent, создайте объект CEvent при необходимости. Укажите имя события необходимо дождаться on, а также укажите, что приложение должно иметь его. Затем можно получить доступ событие, когда конструктор завершает работу. Вызов SetEvent к входу (сделайте доступно) объект события, а затем вызывает Unlock по завершении при доступе к контролируемому ресурсу.

Альтернативный метод, чтобы использовать объекты CEvent добавление переменной типа CEvent как элемент данных, к классу нужно отслеживать. При создании управляемого объекта, вызовите конструктор элемента данных CEvent и указать, следует ли событие получает сигнал, а также тип specifythe объекта события, имя события (если оно будет использоваться через границы процессов), а все атрибуты безопасности.

Чтобы получить доступ к ресурсу проконтролированный объектом CEvent таким образом, сначала создайте переменную или типа CSingleLock или введите CMultiLock в методе доступа данного ресурса. Затем вызовите метод Lock объекта блокировки (например, CMultiLock::Lock). На этом этапе в поток или получит доступ к ресурсу, ожидание ресурсов для освобождения и доступа, увеличения или ожидает ресурс для освобождения, время ожидания и fail получить доступ к ресурсу. В любом случае ресурс был доступ потокобезопасным способом. Для освобождения ресурса, вызов SetEvent для обозначения объект события, а затем использовать метод Unlock объекта блокировки (например, CMultiLock::Unlock) или препятствовал блокировки возразить падение из области.

Дополнительные сведения о том, как использовать объекты CEvent см. в разделе Многопоточность. Использование классов синхронизации.

Пример

// The following demonstrates trivial usage of the CEvent class. 
// A CEvent object is created and passed as a parameter to another  
// thread.  The other thread will wait for the event to be signaled 
// and then exit

UINT __cdecl MyThreadProc(LPVOID lpParameter)
{
   CEvent* pEvent = (CEvent*)(lpParameter);
   VERIFY(pEvent != NULL);

   // Wait for the event to be signaled
   ::WaitForSingleObject(pEvent->m_hObject, INFINITE);

   // Terminate the thread
   ::AfxEndThread(0, FALSE); 
   return 0L;
}

void CEvent_Test()
{
   // Create the CEvent object that will be passed to the thread routine
   CEvent* pEvent = new CEvent(FALSE, FALSE);

   // Create a thread that will wait on the event
   CWinThread* pThread;
   pThread = ::AfxBeginThread(&MyThreadProc, pEvent, 0, 0, CREATE_SUSPENDED, NULL);
   pThread->m_bAutoDelete = FALSE; 
   pThread->ResumeThread();

   // Signal the thread to do the next work item
   pEvent->SetEvent();

   // Wait for the thread to consume the event and return
   ::WaitForSingleObject(pThread->m_hThread, INFINITE); 
   delete pThread;
   delete pEvent;
}
// This example builds upon the previous one. 
// A second thread is created to calculate prime numbers. 
// The main thread will signal the second thread to calulate the next  
// prime number in the series.  The second thread signals the first  
// after each number is calculated. Finally, after several iterations  
// the worker thread is signaled to terminate. 

class CPrimeTest
{
public:
   CPrimeTest()
      : m_pCalcNext(new CEvent(FALSE, FALSE))
      , m_pCalcFinished(new CEvent(FALSE, FALSE))
      , m_pTerminateThread(new CEvent(FALSE, FALSE))
      , m_iCurrentPrime(0)
   {   
      // Create a thread that will calculate the prime numbers
      CWinThread* pThread;
      pThread = ::AfxBeginThread(&PrimeCalcProc, this, 0, 0, CREATE_SUSPENDED, NULL);
      pThread->m_bAutoDelete = FALSE; 
      pThread->ResumeThread();

      // Calcuate the first 10 prime numbers in the series on the thread 
      for(UINT i = 0; i < 10; i++)
      {
         // Signal the thread to do the next work item
         m_pCalcNext->SetEvent();
         // Wait for the thread to complete the current task
         ::WaitForSingleObject(m_pCalcFinished->m_hObject, INFINITE);
         // Print the result
         TRACE(_T("The value of m_iCurrentPrime is: %d\n"), m_iCurrentPrime);
      }

      // Notify the worker thread to exit and wait for it to complete
      m_pTerminateThread->SetEvent();
      ::WaitForSingleObject(pThread->m_hThread, INFINITE); 
      delete pThread;
   }
   ~CPrimeTest()
   {
      delete m_pCalcNext;
      delete m_pCalcFinished;
      delete m_pTerminateThread;
   }

private:
   // Determines whether the given number is a prime number 
   static BOOL IsPrime(INT ThisPrime)
   {
      if(ThisPrime < 2) 
         return FALSE;

      for(INT n = 2; n < ThisPrime; n++)
      {
         if(ThisPrime % n == 0)
            return FALSE;
      }
      return TRUE;
   }

   // Calculates the next prime number in the series 
   static INT NextPrime(INT ThisPrime)
   {
      while(TRUE)
      {
         if(IsPrime(++ThisPrime))
         {
            return ThisPrime;
         }
      }
   }

   // Worker thread responsible for calculating the next prime 
   // number in the series 
   static UINT __cdecl PrimeCalcProc(LPVOID lpParameter)
   {
      CPrimeTest* pThis = static_cast<CPrimeTest*>(lpParameter);
      VERIFY(pThis != NULL);

      VERIFY(pThis->m_pCalcNext != NULL);
      VERIFY(pThis->m_pCalcFinished != NULL);
      VERIFY(pThis->m_pTerminateThread != NULL);

      // Create a CMultiLock object to wait on the various events 
      // WAIT_OBJECT_0 refers to the first event in the array, WAIT_OBJECT_0+1 refers to the second
      CSyncObject* pWaitObjects[] = { pThis->m_pCalcNext, pThis->m_pTerminateThread };
      CMultiLock MultiLock(pWaitObjects, 2L);
      while(MultiLock.Lock(INFINITE, FALSE) == WAIT_OBJECT_0) 
      {         
         // Calculate next prime
         pThis->m_iCurrentPrime = NextPrime(pThis->m_iCurrentPrime);
         // Notify main thread calculation is complete
         pThis->m_pCalcFinished->SetEvent();
       } 

      // Terminate the thread
       ::AfxEndThread(0, FALSE); 
      return 0L;
   }

   CEvent* m_pCalcNext;      // notifies worker thread to calculate next prime
   CEvent* m_pCalcFinished;   // notifies main thread current calculation is complete
   CEvent* m_pTerminateThread;   // notifies worker thread to terminate

   INT m_iCurrentPrime;   // current calculated prime number
};

Иерархия наследования

CObject

CSyncObject

CEvent

Требования

Header: afxmt.h

См. также

Ссылки

Класс CSyncObject

Диаграмма иерархии