Bagikan melalui


CEvent Kelas

Mewakili peristiwa, yang merupakan objek sinkronisasi yang memungkinkan satu utas untuk memberi tahu yang lain bahwa suatu peristiwa telah terjadi.

Sintaks

class CEvent : public CSyncObject

Anggota

Konstruktor Publik

Nama Deskripsi
CEvent::CEvent Membuat CEvent objek.

Metode Publik

Nama Deskripsi
CEvent::PulseEvent Mengatur peristiwa ke tersedia (disinyalir), merilis utas tunggu, dan mengatur peristiwa ke tidak tersedia (tidak ditandatangani).
CEvent::ResetEvent Mengatur peristiwa ke tidak tersedia (tidak ditandatangani).
CEvent::SetEvent Mengatur peristiwa ke tersedia (disinyalir) dan merilis utas tunggu apa pun.
CEvent::Unlock Merilis objek peristiwa.

Keterangan

Peristiwa berguna ketika utas harus tahu kapan harus melakukan tugasnya. Misalnya, utas yang menyalin data ke arsip data harus diberi tahu saat data baru tersedia. Dengan menggunakan CEvent objek untuk memberi tahu alur salin saat data baru tersedia, utas dapat melakukan tugasnya sesegera mungkin.

CEvent objek memiliki dua jenis: manual dan otomatis.

Objek otomatis CEvent secara otomatis kembali ke status tidak bersinyalir (tidak tersedia) setelah setidaknya satu utas dirilis. Secara default, CEvent objek bersifat otomatis kecuali Anda meneruskan TRUE bManualReset parameter selama konstruksi.

Objek manual CEvent tetap dalam status yang ditetapkan oleh SetEvent atau ResetEvent hingga fungsi lain dipanggil. Untuk membuat objek manual CEvent , berikan TRUE bManualReset parameter selama konstruksi.

Untuk menggunakan CEvent objek, buat CEvent objek saat diperlukan. Tentukan nama peristiwa yang ingin Anda tunggu, dan tentukan juga bahwa aplikasi Anda awalnya harus memilikinya. Anda kemudian dapat mengakses peristiwa saat konstruktor kembali. Panggil SetEvent untuk memberi sinyal (sediakan) objek peristiwa lalu panggil Unlock saat Anda selesai mengakses sumber daya yang dikontrol.

Metode alternatif untuk menggunakan CEvent objek adalah menambahkan variabel jenis CEvent sebagai anggota data ke kelas yang ingin Anda kontrol. Selama konstruksi objek terkontrol, panggil konstruktor CEvent anggota data dan tentukan apakah peristiwa awalnya diberi sinyal, dan tentukan juga jenis objek peristiwa yang Anda inginkan, nama peristiwa (jika akan digunakan di seluruh batas proses), dan atribut keamanan apa pun yang Anda inginkan.

Untuk mengakses sumber daya yang CEvent dikontrol oleh objek dengan cara ini, pertama-tama buat variabel jenis CSingleLock atau ketik CMultiLock metode akses sumber daya Anda. Kemudian panggil Lock metode lock objek (misalnya, CMultiLock::Lock). Pada titik ini, utas Anda akan mendapatkan akses ke sumber daya, menunggu sumber daya dirilis dan mendapatkan akses, atau menunggu sumber daya dirilis, waktu habis, dan gagal mendapatkan akses ke sumber daya. Bagaimanapun, sumber daya Anda telah diakses dengan cara yang aman utas. Untuk melepaskan sumber daya, panggil SetEvent untuk memberi sinyal objek peristiwa, lalu gunakan Unlock metode lock objek (misalnya, CMultiLock::Unlock), atau biarkan lock objek berada di luar cakupan.

Untuk informasi selengkapnya tentang cara menggunakan CEvent objek, lihat Multithreading: Cara Menggunakan Kelas Sinkronisasi.

Contoh

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

Hierarki Warisan

CObject

CSyncObject

CEvent

Persyaratan

Header: afxmt.h

CEvent::CEvent

Membuat objek bernama atau tidak bernama CEvent .

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

Parameter

bInitiallyOwn
Jika TRUE, utas untuk CMultilock objek atau CSingleLock diaktifkan. Jika tidak, semua utas yang ingin mengakses sumber daya harus menunggu.

bManualReset
Jika TRUE, menentukan bahwa objek peristiwa adalah peristiwa manual, jika tidak, objek peristiwa adalah peristiwa otomatis.

lpszName
CEvent Nama objek. Harus disediakan jika objek akan digunakan di seluruh batas proses. Jika nama cocok dengan peristiwa yang ada, konstruktor membangun objek baru CEvent yang mereferensikan peristiwa nama tersebut. Jika nama cocok dengan objek sinkronisasi yang ada yang bukan peristiwa, konstruksi akan gagal. Jika NULL, nama akan null.

lpsaAttribute
Atribut keamanan untuk objek peristiwa. Untuk deskripsi lengkap tentang struktur ini, lihat SECURITY_ATTRIBUTES di Windows SDK.

Keterangan

Untuk mengakses atau merilis CEvent objek, buat CMultiLock objek atau CSingleLock dan panggil fungsi dan Unlock anggotanyaLock.

Untuk mengubah status objek menjadi CEvent sinyal (utas tidak perlu menunggu), panggil SetEvent atau PulseEvent. Untuk mengatur status CEvent objek ke nonsignaled (utas harus menunggu), panggil ResetEvent.

Penting

Setelah membuat CEvent objek, gunakan GetLastError untuk memastikan bahwa mutex belum ada. Jika mutex memang ada secara tiba-tiba, itu mungkin menunjukkan proses nakal berjongkok dan mungkin berniat menggunakan mutex dengan berbahaya. Dalam hal ini, prosedur sadar keamanan yang direkomendasikan adalah menutup handel dan melanjutkan seolah-olah ada kegagalan dalam membuat objek.

CEvent::PulseEvent

Mengatur status peristiwa ke sinyal (tersedia), merilis utas tunggu apa pun, dan mengatur ulang ke nonsignaled (tidak tersedia) secara otomatis.

BOOL PulseEvent();

Tampilkan Nilai

Bukan nol jika fungsi berhasil; jika tidak, 0.

Keterangan

Jika peristiwa manual, semua utas tunggu dirilis, peristiwa diatur ke tidak ditandatangani, dan PulseEvent dikembalikan. Jika peristiwa otomatis, satu utas dirilis, peristiwa diatur ke nonsignaled, dan PulseEvent mengembalikan.

Jika tidak ada utas yang menunggu, atau tidak ada utas yang dapat segera dirilis, PulseEvent atur status peristiwa ke nonsignaled dan kembali.

PulseEvent menggunakan fungsi Win32 PulseEvent yang mendasarinya, yang dapat dihapus sesaat dari status tunggu oleh panggilan prosedur asinkron mode kernel. Oleh karena itu, PulseEvent tidak dapat diandalkan dan tidak boleh digunakan oleh aplikasi baru. Untuk informasi selengkapnya, lihat fungsi PulseEvent .

CEvent::ResetEvent

Mengatur status peristiwa ke nonsignaled hingga secara eksplisit diatur ke sinyal oleh SetEvent fungsi anggota.

BOOL ResetEvent();

Tampilkan Nilai

Bukan nol jika fungsi berhasil; jika tidak, 0.

Keterangan

Ini menyebabkan semua utas ingin mengakses kejadian ini untuk menunggu.

Fungsi anggota ini tidak digunakan oleh peristiwa otomatis.

CEvent::SetEvent

Mengatur status peristiwa ke sinyal, merilis utas tunggu apa pun.

BOOL SetEvent();

Tampilkan Nilai

Bukan nol jika fungsi berhasil, jika tidak, 0.

Keterangan

Jika peristiwa manual, peristiwa akan tetap disinyalir hingga ResetEvent dipanggil. Lebih dari satu utas dapat dirilis dalam kasus ini. Jika peristiwa otomatis, peristiwa akan tetap disinyalir hingga satu utas dirilis. Sistem kemudian akan mengatur status peristiwa ke nonsignaled. Jika tidak ada utas yang menunggu, status tetap disinyalir hingga satu utas dirilis.

CEvent::Unlock

Merilis objek peristiwa.

BOOL Unlock();

Tampilkan Nilai

Bukan nol jika utas memiliki objek peristiwa dan peristiwa tersebut adalah peristiwa otomatis; jika tidak, 0.

Keterangan

Fungsi anggota ini dipanggil oleh utas yang saat ini memiliki peristiwa otomatis untuk merilisnya setelah selesai, jika objek mereka lock akan digunakan kembali. lock Jika objek tidak digunakan kembali, fungsi ini akan dipanggil oleh lock destruktor objek.

Lihat juga

CSyncObject Kelas
Bagan Hierarki