Udostępnij za pośrednictwem


Klasa CEvent

Reprezentuje zdarzenia jest obiekt synchronizacji, który umożliwia jeden wątek do innego wystąpienia zdarzenia powiadamiania.

class CEvent : public CSyncObject

Członkowie

Publiczne konstruktory

Nazwa

Opis

CEvent::CEvent

Konstrukcje CEvent obiektu.

Metody publiczne

Nazwa

Opis

CEvent::PulseEvent

Zestawy zdarzenia dostępne (zasygnalizowany) zwalnia oczekujących wątków i ustawia zdarzenie niedostępne (niezasygnalizowany).

CEvent::ResetEvent

Ustawia zdarzenie niedostępne (niezasygnalizowany).

CEvent::SetEvent

Ustawia zdarzenia dostępne (zasygnalizowany) i zwalnia żadnego z oczekujących wątków.

CEvent::Unlock

Zwalnia obiekt zdarzenia.

Uwagi

Zdarzenia są przydatne, gdy wątek musi wiedzieć, kiedy jej zadania.Na przykład wątek, który kopiuje dane do archiwum danych muszą być zgłoszone, gdy dostępne są nowe dane.Za pomocą CEvent obiektu wątku kopii powiadomić, gdy dostępne są nowe dane, wątek można wykonywać swoje zadania jak najszybciej.

CEventobiekty mają dwa typy: ręczne i automatyczne.

Automatyczne CEvent obiekt automatycznie zwraca zasygnalizowane stan (niedostępny), po wydaniu przynajmniej jeden wątek.Domyślnie CEvent obiekt jest automatyczne, o ile przekaże TRUE do bManualReset parametr podczas budowy.

Podręcznik CEvent obiektu pozostanie w stanie ustalonym przez SetEvent lub ResetEvent do innych funkcji.Aby ręcznie utworzyć CEvent obiektów, przekazać TRUE dla bManualReset parametr podczas budowy.

Aby użyć CEvent obiektów, skonstruować CEvent obiektu, gdy jest to wymagane.Określ nazwę zdarzenia, które chcesz czekać, a także określić aplikacji należy ją początkowo własne.Można następnie uzyskać dostęp do zdarzenia, gdy zwraca konstruktora.Wywołanie SetEvent sygnał (udostępnia) obiektu zdarzenia, a następnie wywołanie Unlock po zakończeniu uzyskiwanie dostępu do zasobów kontrolowanych.

Alternatywna metoda za pomocą CEvent obiektów jest dodanie do zmiennej typu CEvent jako członek danych do klasy należy kontrolować.Podczas budowy kontrolowanych obiektu, wywołanie konstruktora CEvent członek danych i określ czy początkowo sygnalizowane jest zdarzenie i również specifythe typu obiektu zdarzenia, należy nazwę zdarzenia (jeśli będzie używany przez granice procesu), a wszelkie zabezpieczenia atrybuty mają.

Aby uzyskać dostęp do zasobów kontrolowanych przez CEvent obiekt w ten sposób, należy najpierw utworzyć zmienną typu albo CSingleLock lub typu CMultiLock metody dostępu zasobu.Następnie wywołać Lock metody lock obiektu (na przykład CMultiLock::Lock).W tym momencie wątek będzie albo uzyskać dostęp do zasobów, oczekiwania zasobu zwolnione i uzyskać dostęp lub poczekaj zasobów do zwolnienia, limit czasu i nie można uzyskać dostęp do zasobu.W każdym przypadku zasób uzyskiwano w sposób bezpieczny wątku.Aby zwolnić zasób, wywołanie SetEvent do sygnału obiektu zdarzenia, a następnie użyj Unlock metody lock obiektu (na przykład CMultiLock::Unlock), lub pozwolić, aby zablokować obiektu mieszczą się poza zakresem.

Aby uzyskać więcej informacji na temat używania CEvent obiektów, zobacz Wielowątkowość: jak używać klas synchronizacji.

Przykład

// 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
};

Hierarchii dziedziczenia

CObject

CSyncObject

CEvent

Wymagania

Nagłówek: afxmt.h

Zobacz też

Informacje

Klasa CSyncObject

Diagram hierarchii