Classe di CEvent
Rappresenta un evento, un oggetto di sincronizzazione che consente a un thread per notificare a un altro che un evento.
class CEvent : public CSyncObject
Membri
Costruttori pubblici
Nome |
Descrizione |
---|---|
Costruisce un oggetto CEvent. |
Metodi pubblici
Nome |
Descrizione |
---|---|
Imposta l'evento su disponibile (segnalato), le versioni thread in attesa e imposta l'evento su non disponibile (non segnalato). |
|
Imposta l'evento su non disponibile (non segnalato). |
|
Imposta l'evento su disponibile (segnalato) e versioni tutti i thread in attesa. |
|
Rilascia l'oggetto evento. |
Note
Gli eventi sono utili quando un thread deve sapere quando eseguire la relativa attività.Ad esempio, un thread che copia dei dati a un archivio dati deve ricevere una notifica quando i nuovi dati disponibili.Utilizzando un oggetto CEvent per notificare alla copia thread quando i nuovi dati sono disponibili, il thread può eseguire la relativa attività il prima possibile.
Gli oggetti diCEvent dispongono di due tipi: manuale e automatico.
Restituisce automatici di un oggetto CEvent automaticamente a uno stato non disponibile) non segnalato almeno un thread viene rilasciato.Per impostazione predefinita, un oggetto CEvent è automatico a meno che non venga passato TRUE per il parametro bManualReset durante la costruzione.
Un oggetto CEvent manuali rimane nello stato impostato da SetEvent o da ResetEvent fino a chiamare un'altra funzione.Per creare un oggetto manuale CEvent, passare TRUE per il parametro bManualReset durante la costruzione.
Per utilizzare un oggetto CEvent, costruire l'oggetto CEvent quando necessario.Specificare il nome dell'evento che si desidera attendere su e specificare che l'applicazione deve inizialmente possederla.È quindi possibile accedere all'evento al completamento del costruttore.Chiamare SetEvent per segnalare (rendere) l'oggetto evento e quindi chiamare Sblocca al termine di accedere alla risorsa controllata.
Un metodo alternativo per gli oggetti CEvent è possibile aggiungere una variabile di tipo CEvent come un membro dati alla classe che si desidera controllare.Durante la costruzione dell'oggetto selezionato, chiamare il costruttore del membro dati CEvent e specificare se l'evento è inizialmente segnalato nonché tipo di specifythe di oggetto evento desiderato, il nome dell'evento (se verrà utilizzato oltre i limiti dei processi) e di tutti gli attributi di sicurezza desiderate.
Per accedere a una risorsa controllata da un oggetto CEvent in questo modo, creare innanzitutto una variabile di tipo CSingleLock o digitare CMultiLock nel metodo di accesso alla risorsa.Chiamare il metodo Lock dell'oggetto di blocco (ad esempio, CMultiLock::Lock).In questa fase, il thread o accederà alla risorsa, attendere che la risorsa da rilasciare e accederà, o attendere che la risorsa da rilasciare, è scaduto e non riesce ad accedere alla risorsa.Tuttavia, la risorsa è stata accedere in modo thread-safe.Per rilasciare la risorsa, chiamare SetEvent per segnalare l'oggetto evento e quindi il metodo Unlock dell'oggetto di blocco (ad esempio, CMultiLock::Unlock, oppure lasciare il blocco nella UIambito.
Per ulteriori informazioni su come utilizzare gli oggetti CEvent, vedere Multithreading: utilizzo delle classi di sincronizzazione.
Esempio
// 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
};
Gerarchia di ereditarietà
CEvent
Requisiti
Header: afxmt.h