Clase de CEvent
Representa un evento, que es un objeto de sincronización que permite que un subproceso para notificar a otro que se ha producido un evento.
class CEvent : public CSyncObject
Members
Constructores públicos
Name |
Descripción |
---|---|
Crea un objeto CEvent. |
Métodos públicos
Name |
Descripción |
---|---|
Establece el evento en los subprocesos en espera disponibles (notifican), de las versiones, y establece el evento a ocupada (nonsignaled). |
|
Establece el evento en ocupada (nonsignaled). |
|
Establece el evento en disponibles (designado) y los libera cualquier subproceso en espera. |
|
Libera el objeto de evento. |
Comentarios
Los eventos son útiles cuando un subproceso debe saber cuándo realizar la tarea.Por ejemplo, un subproceso que copia datos a un archivo de datos debe recibir una notificación cuando los nuevos datos está disponible.Utilizando un objeto de CEvent para notificar la copia subproceso cuando los nuevos datos disponible, el subproceso puede realizar la tarea lo más rápidamente posible.
los objetos deCEvent tienen dos tipos: manual y automático.
Un objeto automático de CEvent cambia automáticamente un estado (no disponible) no señalado después de que al menos un subproceso se libere.De forma predeterminada, un objeto de CEvent es automática a menos que pase TRUE para el parámetro de bManualReset durante la construcción.
Un objeto de CEvent de manual permanece en el estado establecida por SetEvent o ResetEvent hasta que se llama a otra función.para crear un objeto manual de CEvent , pase TRUE para el parámetro de bManualReset durante la construcción.
Para utilizar un objeto de CEvent , cree el objeto de CEvent cuando sea necesario.Especifique el nombre del evento que desea esperar, y también especifíquelo que la aplicación debe poseerlo inicialmente.Podrá obtener acceso al evento cuando el constructor devuelve.Llame a SetEvent para informes (está disponible) el objeto de evento y después llamar a Unlock cuando termine teniendo acceso al recurso controlado.
Un método alternativo para utilizar los objetos de CEvent es agregar una variable de CEvent escrito como un miembro de datos a la clase que desea supervisar.Durante la construcción del objeto controlado, llame al constructor del miembro de datos de CEvent y especifíquelo si el evento se notificará inicialmente, así como tipo de specifythe de objeto del evento que desea, el nombre del evento (si utiliza los límites de un proceso), y cualquier atributo de seguridad desee.
Para tener acceso a un recurso controlado por un objeto de CEvent de esta manera, primero cree una variable de CSingleLock tipo o escriba CMultiLock en el método de acceso de recursos.Llamar a continuación al método de Lock de objeto de bloqueo (por ejemplo, CMultiLock:: bloqueo).En este punto, el subproceso accederá el recurso, espere a que el recurso sea liberado y accederá, o esperará el recurso que se produce al mercado, el tiempo de espera, y el error para obtener acceso al recurso.En cualquier caso, el recurso se ha tenido acceso de una manera segura para subprocesos.Para liberar el recurso, llame a SetEvent para informar del objeto de evento, y utilice el método de Unlock de objeto de bloqueo (por ejemplo, CMultiLock:: Unlock), o deje el objeto de bloqueo situarse fuera de ámbito.
Para obtener más información sobre cómo utilizar los objetos de CEvent , vea Subprocesamiento múltiple: Uso de las clases de sincronización.
Ejemplo
// 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
};
Jerarquía de herencia
CEvent
Requisitos
encabezado: afxmt.h