CEvent 類別
表示事件,是同步物件可讓執行緒向類別上的事件發生。
class CEvent : public CSyncObject
Members
公用建構函式
名稱 |
描述 |
---|---|
建構 CEvent 物件。 |
公用方法
名稱 |
描述 |
---|---|
將事件設定為可用 (信號) 版本,等候執行緒的和集合事件為無法使用 (非)。 |
|
將事件設定為無法使用 (非)。 |
|
將事件加入至可用 (信號) 和釋放所有等候中的執行緒。 |
|
發行事件物件。 |
備註
指定執行緒時必須知道執行其工作時,事件會很有用處。例如,複製至資料檔案的執行緒必須告知,當新資料可用時。您可以使用告知複本的 CEvent 物件執行緒,新增資料可用,執行緒可以儘快執行其工作。
CEvent 具有兩種類型:手動和自動。
將自動 CEvent 物件自動復原為未收到信號的 (無法使用) 狀態,在釋放之後至少一個執行緒。根據預設,在中,除非您在建構時,您可以 bManualReset 參數的 TRUECEvent 物件會自動進行。
方針 CEvent 物件在 SetEvent 或 ResetEvent 設定的狀態會暫停,直到另一個函式呼叫。若要建立手動 CEvent 物件,請在建構期間傳遞 bManualReset 參數的 TRUE 。
如果需要時,要使用 CEvent 物件,請 CEvent 建構物件。指定要等候事件的名稱,並指定您的應用程式應初始擁有它。當建構函式傳回時,您可以存取事件。呼叫 SetEvent 信號 (可提供事件) 物件,然後呼叫 解除鎖定 在進行存取控制資源時。
替代方法是使用 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
};
繼承階層架構
CEvent
需求
Header: afxmt.h