CEvent クラス

イベントを表します。これは、あるスレッドがイベントが発生したことを別のスレッドに通知できるようにする同期オブジェクトです。

構文

class CEvent : public CSyncObject

メンバー

パブリック コンストラクター

名前 説明
CEvent::CEvent CEvent オブジェクトを構築します。

パブリック メソッド

名前 説明
CEvent::PulseEvent イベントを使用可能 (シグナル) に設定し、待機中のスレッドを解放し、イベントを使用不可 (非割り当て) に設定します。
CEvent::ResetEvent イベントを使用不可 (非署名) に設定します。
CEvent::SetEvent イベントを使用可能 (シグナル) に設定し、待機しているスレッドを解放します。
CEvent::Unlock イベント オブジェクトを解放します。

解説

イベントは、スレッドがそのタスクを実行するタイミングを知る必要がある場合に便利です。 たとえば、データアーカイブにデータをコピーするスレッドは、新しいデータが使用可能になったときに通知を受け取る必要があります。 オブジェクトを CEvent 使用して、新しいデータが使用可能になったときにコピー スレッドに通知することで、スレッドはできるだけ早くタスクを実行できます。

CEvent オブジェクトには、手動と自動の 2 種類があります。

自動 CEvent オブジェクトは、少なくとも 1 つのスレッドが解放された後、非シグナル状態 (使用不可) に自動的に戻ります。 既定では、構築中にパラメーターを CEventTRUE さない限り、 bManualReset オブジェクトは自動です。

手動CEventオブジェクトは、他の関数が呼び出されるまで設定されたSetEventResetEvent状態のままです。 手動CEventオブジェクトを作成するには、構築中にパラメーターをbManualResetTRUEします。

オブジェクトを CEvent 使用するには、必要に応じてオブジェクトを CEvent 構築します。 待機するイベントの名前を指定し、アプリケーションが最初にイベントを所有するように指定します。 その後、コンストラクターが戻ったときにイベントにアクセスできます。 イベント オブジェクトを通知 (使用可能にする) を呼び出 SetEvent し、制御されたリソースへのアクセスが完了したら呼び出 Unlock します。

オブジェクトを使用 CEvent する別の方法は、制御するクラスにデータ メンバーとして型 CEvent の変数を追加することです。 制御されたオブジェクトの構築中に、データ メンバーのコンストラクターを CEvent 呼び出し、イベントが最初に通知されるかどうかを指定し、必要なイベント オブジェクトの種類、イベントの名前 (プロセス境界を越えて使用される場合)、および必要なセキュリティ属性を指定します。

この方法でオブジェクトによって制御されるCEventリソースにアクセスするには、まず、リソースのアクセス方法で型または型CSingleLockCMultiLockのいずれかの変数を作成します。 次に、オブジェクトの Lock メソッドを lock 呼び出します (例: CMultiLock::Lock)。 この時点で、スレッドはリソースへのアクセス権を取得するか、リソースが解放されてアクセスを得るのを待つか、リソースが解放されるのを待ってタイムアウトし、リソースへのアクセスに失敗します。 いずれの場合も、リソースにはスレッド セーフな方法でアクセスされています。 リソースを解放するには、イベント オブジェクトを通知する呼び出しを呼び出SetEventし、オブジェクトのlockメソッド (たとえば、) を使用Unlockするか、CMultiLock::Unlockオブジェクトがlockスコープ外に落ちることを許可します。

オブジェクトの使用方法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 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
};

継承階層

CObject

CSyncObject

CEvent

必要条件

ヘッダー:afxmt.h

CEvent::CEvent

名前付きオブジェクトまたは名前のないオブジェクトを CEvent 構築します。

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

パラメーター

bInitiallyOwn
場合TRUEは、またはCSingleLockオブジェクトのCMultilockスレッドが有効です。 それ以外の場合、リソースにアクセスするすべてのスレッドは待機する必要があります。

bManualReset
の場合 TRUEは、イベント オブジェクトが手動イベントであることを指定します。それ以外の場合、イベント オブジェクトは自動イベントです。

lpszName
CEvent オブジェクトの名前。 オブジェクトがプロセス境界を越えて使用される場合は、指定する必要があります。 名前が既存のイベントと一致する場合、コンストラクターはその名前のイベントを参照する新しい CEvent オブジェクトをビルドします。 名前がイベントではない既存の同期オブジェクトと一致する場合、構築は失敗します。 の場合 NULL、名前は null になります。

lpsaAttribute
イベント オブジェクトのセキュリティ属性。 この構造の詳細については、Windows SDK を参照してください SECURITY_ATTRIBUTES

解説

オブジェクトにアクセスまたは解放CEventするには、オブジェクトをCMultiLockCSingleLock作成し、そのオブジェクトとUnlockメンバー関数をLock呼び出します。

オブジェクトの状態を CEvent シグナル通知に変更するには (スレッドは待機する必要はありません)、呼び出し SetEvent または PulseEvent. オブジェクトの CEvent 状態を非署名 (スレッドは待機する必要があります) に設定するには、次を呼び出します ResetEvent

重要

オブジェクトを作成した CEvent 後、ミューテックスがまだ存在していないことを確認するために使用 GetLastError します。 ミューテックスが予期せず存在していた場合は、不正なプロセスがしゃがみ込み、ミューテックスを悪意を持って使用しようとしている可能性があることを示している可能性があります。 この場合、推奨されるセキュリティ意識の高い手順は、ハンドルを閉じて、オブジェクトの作成に失敗したかのように続行することです。

CEvent::PulseEvent

イベントの状態をシグナル通知 (使用可能) に設定し、待機中のスレッドをすべて解放し、自動的に非署名 (使用不可) にリセットします。

BOOL PulseEvent();

戻り値

関数が成功した場合は 0 以外。それ以外の場合は 0。

解説

イベントが手動の場合、待機しているすべてのスレッドが解放され、イベントは非署名に設定され PulseEvent 、返されます。 イベントが自動で、1 つのスレッドが解放され、イベントが非署名に設定され PulseEvent 、返されます。

待機しているスレッドがない場合、またはスレッドをすぐに解放できない場合は、 PulseEvent イベントの状態を非署名に設定して返します。

PulseEvent は基になる Win32 PulseEvent 関数を使用します。これは、カーネル モードの非同期プロシージャ呼び出しによって待機状態から一時的に削除される可能性があります。 そのため、信頼性が低く、 PulseEvent 新しいアプリケーションでは使用しないでください。 詳細については、PulseEvent 関数に関するページを参照してください。

CEvent::ResetEvent

メンバー関数によってシグナル通知に明示的に設定されるまで、イベントの状態を非署名に SetEvent 設定します。

BOOL ResetEvent();

戻り値

関数が成功した場合は 0 以外。それ以外の場合は 0。

解説

これにより、このイベントにアクセスするすべてのスレッドが待機します。

このメンバー関数は、自動イベントでは使用されません。

CEvent::SetEvent

イベントの状態をシグナル通知に設定し、待機中のスレッドを解放します。

BOOL SetEvent();

戻り値

関数が成功した場合は 0 以外、それ以外の場合は 0。

解説

イベントが手動の場合、イベントは再メイン呼び出されるまでResetEvent通知されます。 この場合、複数のスレッドを解放できます。 イベントが自動の場合、1 つのスレッドが解放されるまでメインイベントが再通知されます。 その後、システムはイベントの状態を非署名に設定します。 待機しているスレッドがない場合は、1 つのスレッドが解放されるまで状態が再メイン通知されます。

CEvent::Unlock

イベント オブジェクトを解放します。

BOOL Unlock();

戻り値

スレッドがイベント オブジェクトを所有していて、イベントが自動イベントの場合は 0 以外。それ以外の場合は 0。

解説

このメンバー関数は、オブジェクトが再利用される場合 lock に、完了した後に解放する自動イベントを現在所有しているスレッドによって呼び出されます。 オブジェクトを lock 再利用しない場合、この関数はオブジェクトの lock デストラクターによって呼び出されます。

関連項目

CSyncObject クラス
階層図