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
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.