CEvent, classe
Représente un événement, un objet de synchronisation qui permet à un thread d'informer les autres qu'un événement s'est produit.
class CEvent : public CSyncObject
Membres
Constructeurs publics
Nom |
Description |
---|---|
Construit un objet CEvent. |
Méthodes publiques
Nom |
Description |
---|---|
Place l'événement à des threads en attente disponibles signalé (), de versions, et aux ensembles l'événement à pas disponible (non signalé). |
|
Place l'événement à pas disponible (non signalé). |
|
Place l'événement à disponible (signalé) et aux versions tous les threads en attente. |
|
Libère l'objet événement. |
Notes
Les événements sont utiles lorsqu'un thread doit savoir quand effectuer la tâche. Par exemple, il doit annoncer un thread qui copie des données à une archive de données lorsque les nouvelles données sont disponibles. À l'aide d'un objet d' CEvent pour indiquer à la copie thread lorsque les nouvelles données sont disponibles, le thread peut effectuer sa tâche dès que possible.
Les objets d'CEvent ont deux types : manuels et automatique.
Un objet automatique d' CEvent revient automatiquement à un état (non disponible) non signalé après avoir au moins un thread soit libéré. Par défaut, un objet d' CEvent est automatique à moins que vous passer TRUE du paramètre d' bManualReset pendant la construction.
Un objet d' CEvent de manuel reste dans l'état défini par SetEvent ou ResetEvent jusqu'à ce que l'autre fonction appelée. Pour créer un objet manuel d' CEvent , exécutez TRUE du paramètre d' bManualReset pendant la construction.
Pour utiliser un objet d' CEvent , construisez l'objet d' CEvent lorsque nécessaire. Spécifiez le nom de l'événement à attendre, et le spécifiez également que votre application doit initialement le propriétaire. Vous pouvez ensuite accéder à l'événement lorsque le constructeur retourne. Appelez SetEvent pour signaler (rendre disponible) l'objet événement puis appeler déverrouillez lorsque vous avez terminé de l'accès à la ressource contrôlée.
Une autre méthode pour l'utilisation des objets d' CEvent consiste à ajouter une variable de type CEvent comme une donnée membre à la classe que vous souhaitez extraire. Pendant la construction de l'objet contrôlé, appelez le constructeur de la donnée membre d' CEvent et le spécifier si l'événement est initialement signalé, et également type de specifythe d'objet événement à, le nom de l'événement (s'il est utilisé au delà de les limites de processus), et tous les attributs de sécurité vous souhaitez.
Pour accéder à une ressource contrôlée par un objet d' CEvent de cette manière, commencez par créer une variable de type CSingleLock ou tapez CMultiLock dans la méthode d'accès de votre ressource. Appelez la méthode d' Lock d'objets lock (par exemple, CMultiLock::Lock). À ce stade, votre thread accédera à la ressource attente, la ressource à libérer et accédera, ou attend la ressource à libérer, l'heure, et l'échec d'accéder à la ressource. Dans tous les cas, la ressource a été accessible en mode thread-safe. Pour libérer les ressources, l'appel SetEvent pour signaler l'objet événement, puis pour utiliser la méthode d' Unlock d'objets lock (par exemple, CMultiLock::Unlock), ou let l'objet lock blocage hors de portée.
Pour plus d'informations sur l'utilisation des objets d' CEvent , consultez Multithreading : comment utiliser les classes de synchronisation.
Exemple
// 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
};
Hiérarchie d'héritage
CEvent
Configuration requise
Header: afxmt.h