Share via


CEvent-klasse

Opmerking

De Microsoft Foundation Classes-bibliotheek (MFC) wordt nog steeds ondersteund. We voegen echter geen functies meer toe of werken de documentatie bij.

Vertegenwoordigt een gebeurtenis, een synchronisatieobject waarmee de ene thread een melding kan sturen dat er een gebeurtenis is opgetreden.

Syntaxis

class CEvent : public CSyncObject

Leden

Openbare constructors

Naam Description
CEvent::CEvent Maakt een CEvent object.

Openbare methoden

Naam Description
CEvent::PulseEvent Hiermee stelt u de gebeurtenis in op beschikbaar (gesignaleerd), worden wachtende threads uitgebracht en wordt de gebeurtenis ingesteld op niet beschikbaar (niet-ondertekend).
CEvent::ResetEvent Hiermee stelt u de gebeurtenis in op niet beschikbaar (niet-ondertekend).
CEvent::SetEvent Hiermee stelt u de gebeurtenis in op beschikbaar (gesignaleerd) en worden eventuele wachtende threads uitgebracht.
CEvent::Unlock Hiermee wordt het gebeurtenisobject vrijgegeven.

Opmerkingen

Gebeurtenissen zijn handig wanneer een thread moet weten wanneer de taak moet worden uitgevoerd. Een thread waarmee gegevens worden gekopieerd naar een gegevensarchief, moet bijvoorbeeld worden gewaarschuwd wanneer er nieuwe gegevens beschikbaar zijn. Door een CEvent object te gebruiken om de kopieerthread te waarschuwen wanneer er nieuwe gegevens beschikbaar zijn, kan de thread de taak zo snel mogelijk uitvoeren.

CEvent objecten hebben twee typen: handmatig en automatisch.

Een automatisch CEvent object keert automatisch terug naar een niet-gesigneerde status (niet beschikbaar) nadat ten minste één thread is vrijgegeven. Een object is standaard CEvent automatisch, tenzij u de parameter tijdens de bManualReset constructie doorgeeftTRUE.

Een handmatig CEvent object blijft in de status ingesteld door SetEvent of ResetEvent totdat de andere functie wordt aangeroepen. Als u een handmatig CEvent object wilt maken, geeft TRUE u de parameter tijdens de bManualReset constructie door.

Als u een CEvent object wilt gebruiken, maakt u het CEvent object wanneer dit nodig is. Geef de naam op van de gebeurtenis waarop u wilt wachten en geef ook op dat uw toepassing in eerste instantie eigenaar moet zijn van de gebeurtenis. U kunt vervolgens toegang krijgen tot de gebeurtenis wanneer de constructor terugkeert. Aanroep SetEvent om het gebeurtenisobject aan te geven (beschikbaar te maken) en vervolgens aan te roepen Unlock wanneer u klaar bent met het openen van de beheerde resource.

Een alternatieve methode voor het gebruik CEvent van objecten is het toevoegen van een variabele van het type CEvent als gegevenslid aan de klasse die u wilt beheren. Roep tijdens de constructie van het gecontroleerde object de constructor van het CEvent gegevenslid aan en geef op of de gebeurtenis in eerste instantie wordt gesignaleerd en geef ook het gewenste type gebeurtenisobject op, de naam van de gebeurtenis (als deze wordt gebruikt binnen procesgrenzen) en eventuele gewenste beveiligingskenmerken.

Als u op deze manier toegang wilt krijgen tot een resource die wordt beheerd door een CEvent object, maakt u eerst een variabele van het type CSingleLock of typt CMultiLock u de toegangsmethode van uw resource. Roep vervolgens de Lock methode van het lock object aan (bijvoorbeeld CMultiLock::Lock). Op dit moment krijgt uw thread toegang tot de resource, wacht u tot de resource is vrijgegeven en krijgt u toegang, of wacht u tot de resource is vrijgegeven, treedt er een time-out op en krijgt u geen toegang tot de resource. In elk geval is uw resource op een threadveilige manier geopend. Als u de resource wilt vrijgeven, roept SetEvent u aan om het gebeurtenisobject aan te geven en gebruikt u vervolgens de Unlock methode van het lock object (bijvoorbeeld CMultiLock::Unlock) of laat het lock object buiten het bereik vallen.

Zie Multithreading: De synchronisatieklassen gebruiken voor meer informatie over het gebruik CEvent van objecten.

Example

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

Overnamehiërarchie

CObject

CSyncObject

CEvent

Requirements

Rubriek:afxmt.h

CEvent::CEvent

Maakt een benoemd of niet-benoemd CEvent object.

CEvent(
    BOOL bInitiallyOwn = FALSE,
    BOOL bManualReset = FALSE,
    LPCTSTR lpszName = NULL,
    LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);

Parameterwaarden

bInitiallyOwn
Als TRUEde thread voor het CMultilock of CSingleLock object is ingeschakeld. Anders moeten alle threads die toegang tot de resource willen krijgen, wachten.

bManualReset
Als TRUE, geeft u aan dat het gebeurtenisobject een handmatige gebeurtenis is, anders is het gebeurtenisobject een automatische gebeurtenis.

lpszName
Naam van het CEvent object. Moet worden opgegeven als het object wordt gebruikt voor procesgrenzen. Als de naam overeenkomt met een bestaande gebeurtenis, bouwt de constructor een nieuw CEvent object dat verwijst naar de gebeurtenis van die naam. Als de naam overeenkomt met een bestaand synchronisatieobject dat geen gebeurtenis is, mislukt de constructie. Als NULL, is de naam null.

lpsaAttribute
Beveiligingskenmerken voor het gebeurtenisobject. Zie de Windows SDK voor een volledige beschrijving van deze structuur SECURITY_ATTRIBUTES .

Opmerkingen

Als u een CEvent object wilt openen of vrijgeven, maakt u een CMultiLock of CSingleLock object en roept u de Lock functies en Unlock leden aan.

Als u de status van een CEvent object wilt wijzigen in gesignaleerd (threads hoeven niet te wachten), roept SetEvent u aan of PulseEvent. Als u de status van een CEvent object wilt instellen op niet-ondertekende objecten (threads moeten wachten), roept u aan ResetEvent.

Belangrijk

Nadat u het CEvent object hebt gemaakt, moet GetLastError u ervoor zorgen dat de mutex nog niet bestaat. Als de mutex onverwacht bestond, kan dit erop wijzen dat een rogue proces squatting is en mogelijk van plan is om de mutex kwaadwillend te gebruiken. In dit geval is de aanbevolen beveiligingsbewuste procedure om de ingang te sluiten en door te gaan alsof er een fout is opgetreden bij het maken van het object.

CEvent::PulseEvent

Hiermee stelt u de status van de gebeurtenis in op gesignaleerd (beschikbaar), worden alle wachtende threads vrijgegeven en wordt deze automatisch opnieuw ingesteld op niet-ondertekend (niet beschikbaar).

BOOL PulseEvent();

Retourwaarde

Niet-nul als de functie is geslaagd; anders 0.

Opmerkingen

Als de gebeurtenis handmatig is, worden alle wachtende threads vrijgegeven, wordt de gebeurtenis ingesteld op niet-ondertekend en PulseEvent wordt deze geretourneerd. Als de gebeurtenis automatisch is, wordt één thread vrijgegeven, wordt de gebeurtenis ingesteld op niet-ondertekend en PulseEvent wordt deze geretourneerd.

Als er geen threads wachten of als er geen threads direct kunnen worden vrijgegeven, PulseEvent stelt u de status van de gebeurtenis in op niet-ondertekende en geretourneerde threads.

PulseEvent maakt gebruik van de onderliggende Win32-functie PulseEvent , die tijdelijk uit de wachtstatus kan worden verwijderd door een asynchrone procedureaanroep in de kernelmodus. PulseEvent Daarom is dit onbetrouwbaar en mag niet worden gebruikt door nieuwe toepassingen. Zie de PulseEvent functie voor meer informatie.

CEvent::ResetEvent

Hiermee stelt u de status van de gebeurtenis in op niet-ondertekend totdat deze expliciet is ingesteld op gesignaleerd door de SetEvent lidfunctie.

BOOL ResetEvent();

Retourwaarde

Niet-nul als de functie is geslaagd; anders 0.

Opmerkingen

Dit zorgt ervoor dat alle threads die toegang tot deze gebeurtenis willen krijgen, wachten.

Deze lidfunctie wordt niet gebruikt door automatische gebeurtenissen.

CEvent::SetEvent

Hiermee stelt u de status van de gebeurtenis in op signalering, waarbij eventuele wachtende threads worden vrijgegeven.

BOOL SetEvent();

Retourwaarde

Niet-nul als de functie is geslaagd, anders 0.

Opmerkingen

Als de gebeurtenis handmatig is, blijft de gebeurtenis gesignaleerd totdat ResetEvent deze wordt aangeroepen. In dit geval kunnen meer dan één thread worden vrijgegeven. Als de gebeurtenis automatisch is, blijft de gebeurtenis gesignaleerd totdat één thread wordt vrijgegeven. Het systeem stelt vervolgens de status van de gebeurtenis in op niet-ondertekend. Als er geen threads wachten, blijft de status gesignaleerd totdat één thread wordt vrijgegeven.

CEvent::Unlock

Hiermee wordt het gebeurtenisobject vrijgegeven.

BOOL Unlock();

Retourwaarde

Niet-nul als de thread het gebeurtenisobject bezit en de gebeurtenis een automatische gebeurtenis is; anders 0.

Opmerkingen

Deze lidfunctie wordt aangeroepen door threads die momenteel eigenaar zijn van een automatische gebeurtenis om deze vrij te geven nadat ze klaar zijn, als hun lock object opnieuw moet worden gebruikt. Als het lock object niet opnieuw moet worden gebruikt, wordt deze functie aangeroepen door de destructor van het lock object.

Zie ook

CSyncObject klasse
Hiërarchiegrafiek