CEvent Class

表示一个事件,是同步对象允许一个线程通知另一个操作的。

class CEvent : public CSyncObject

成员

公共构造函数

名称

说明

CEvent::CEvent

构造 CEvent 对象。

公共方法

名称

说明

CEvent::PulseEvent

将等待线程的活动为可用(终止),版本,并将事件设置可用(nonsignaled)。

CEvent::ResetEvent

将事件设置可用(nonsignaled)。

CEvent::SetEvent

将事件设置可用(终止)和版本所有等待线程。

CEvent::Unlock

释放事件对象。

备注

当线程时必须知道执行其任务时,事件非常有用。 例如,复制的线程传递数据的数据存档必须注意,在新数据可用时。 通过使用通知该副本的 CEvent 对象的线程,在新数据可用,线程可以尽快执行其任务。

CEvent 对象有两种类型:手动和自动。

一个自 CEvent 对象自动恢复为非终止(可用)状态,在释放后至少有一个线程。 默认情况下,除非在构造期间,通过 bManualReset 参数的 TRUECEvent 对象是自动的。

准则 CEvent 对象在 SetEventResetEvent 设置的状态保持,直到另一个函数调用。 若要创建手动 CEvent 对象,请在构造时传递 bManualReset 参数的 TRUE。

在需要时,要使用 CEvent 对象,请构造 CEvent 对象。 指定要等待事件的名称,并指定应用程序最初应拥有它。 当构造函数返回时,您可以访问该事件。 调用 SetEvent 发出信号(可用时)事件对象并调用 unlock,在执行这种访问受控资源后。

另一种方法用于 CEvent 对象将添加 CEvent 类型的变量,要控件的选件类的数据成员。 在控制构造对象时,只需调用 CEvent 数据成员的构造函数并指定事件最初是否收到信号,然后的事件对象的specifythe类型需要,事件的名称(如果它将用作进程边界)和所需的任何安全特性。

访问 CEvent 对象来控件的资源,首先创建类型 CSingleLock 的变量或键入在资源访问方法的 CMultiLock。 然后调用锁定对象(例如,CMultiLock::Lock)的 Lock 方法。 此时,您的线程对该资源将能够访问,等待资源释放并且能够访问或等待资源释放,时间和未对该资源的访问权。 在任一情况下,您的资源访问了采用线程安全的方式。 若要释放资源,调用 SetEvent 用于通知事件对象,然后使用锁定对象的 Unlock 方法(例如,CMultiLock::Unlock),或者允许锁定对象由超出范围。

有关如何使用 CEvent 对象的更多信息,请参见 多线程处理:如何使用同步类

示例

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

继承层次结构

CObject

CSyncObject

CEvent

要求

Header: afxmt.h

请参见

参考

CSyncObject 类

层次结构图