Sdílet prostřednictvím


Třída CEvent

Představuje událost, což je objekt synchronizace umožňuje upozornit jiného, že došlo k události jeden podproces.

class CEvent : public CSyncObject

Členy

Veřejné konstruktory

Název

Description

CEvent::CEvent

Konstrukce CEvent objektu.

Veřejné metody

Název

Description

CEvent::PulseEvent

Nastaví signalizováno následným události k dispozici (tichem), uvolní podprocesy čekání a nastaví události není k dispozici (nonsignaled).

CEvent::ResetEvent

Nastaví události není k dispozici (nonsignaled).

CEvent::SetEvent

Nastaví události k dispozici (signalizovaném) a uvolní všechny podprocesy čekání.

CEvent::Unlock

Vydává objektu události.

Poznámky

Události jsou užitečné, pokud podproces musí vědět, kdy jeho úlohu provést.Například podproces, který zkopíruje data do archivu dat musí být oznámena, když je k dispozici nová data.Pomocí CEvent objektu upozornit podproces kopie, když je k dispozici nová data podprocesu co nejdříve provést jeho úkolu.

CEventobjekty mají dva typy: ruční a automatické.

Automatické CEvent objekt automaticky vrátí do stavu bez signalizováno následným tichem (nedostupné) po vydání alespoň jeden podproces.Standardně CEvent objektu je automatická, pokud předáte TRUE pro bManualReset parametr během stavby.

Ruční CEvent objektu zůstane ve stavu nastavit SetEvent nebo ResetEvent dokud jiné funkce.Ruční vytvoření CEvent objekt, předat TRUE pro bManualReset parametr během stavby.

Použít CEvent objekt, sestavit CEvent objektu, pokud je to požadováno.Zadejte název události, kterou chcete čekat na a také určit, aby aplikace měla zpočátku vlastní ji.Máte přístup při vrátí konstruktor událost.Volání SetEvent signál (zpřístupnit) objektu události a poté volání Unlock po dokončení přístupu k prostředku řízené.

Alternativní metoda pomocí CEvent objektů je přidat proměnnou typu CEvent jako člena třídy chcete ovládací prvek.Během stavby řízené objekt volání konstruktoru CEvent datový člen a určit, zda událost je signalizováno následným původně tichem a také specifythe typu objektu události, má název události (Pokud se použije přes hranice procesu), veškeré zabezpečení atributy chcete.

Přístup k prostředku řízena CEvent objekt tímto způsobem, nejprve vytvořit proměnné typu buď CSingleLock nebo CMultiLock v metodě přístup k prostředku.Zavolejte Lock metodu lock objektu (například CMultiLock::Lock).V tomto okamžiku vaší podproces bude buď získat přístup k prostředku, čekat na prostředku uvolní a získat přístup nebo prostředek k uvolnění čekat, časový limit a nepodaří získat přístup k prostředku.V každém případě prostředek přístupu způsobem podprocesu.Uvolnit prostředek, zavolejte na SetEvent signál objekt události, a potom pomocí Unlock metodu lock objektu (například CMultiLock::Unlock), nebo nechat objektu zámku spadají mimo rozsah.

Další informace o použití CEvent objekty, viz Multithreading: Jak používat synchronizační třídy.

Příklad

// 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 dědičnosti

CObject

CSyncObject

CEvent

Požadavky

Záhlaví: afxmt.h

Viz také

Referenční dokumentace

Třída CSyncObject

Graf hierarchie