Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Megjegyzés:
A Microsoft Foundation Classes (MFC) könyvtár továbbra is támogatott. A továbbiakban azonban nem adunk hozzá funkciókat, és nem frissítjük a dokumentációt.
Olyan eseményt jelöl, amely egy szinkronizálási objektum, amely lehetővé teszi, hogy az egyik szál értesítse a másikat egy eseményről.
Szemantika
class CEvent : public CSyncObject
Tagok
Nyilvános konstruktorok
| Név | Description |
|---|---|
CEvent::CEvent |
Egy CEvent objektumot hoz létre. |
Nyilvános metódusok
| Név | Description |
|---|---|
CEvent::PulseEvent |
Beállítja az eseményt elérhetőre (jelezve), felszabadítja a várakozási szálakat, és az eseményt elérhetetlenné (nem aláírtra) állítja. |
CEvent::ResetEvent |
Az eseményt nem elérhetőnek (nem aláírtnak) állítja be. |
CEvent::SetEvent |
Beállítja az eseményt elérhetőre (jelezve), és felszabadítja a várakozó szálakat. |
CEvent::Unlock |
Felszabadítja az eseményobjektumot. |
Megjegyzések
Az események akkor hasznosak, ha egy szálnak tudnia kell, hogy mikor kell elvégeznie a feladatát. Ha például egy adatarchívumba másol adatokat, értesítést kell kapnia arról, ha új adatok állnak rendelkezésre. Ha objektum használatával CEvent értesíti a másolási szálat, ha új adatok állnak rendelkezésre, a szál a lehető leghamarabb végrehajthatja a feladatát.
CEvent az objektumoknak két típusa van: manuális és automatikus.
Az automatikus CEvent objektumok automatikusan visszaállnak egy nem jelű (nem elérhető) állapotba legalább egy szál felszabadítása után. Alapértelmezés szerint egy CEvent objektum automatikus, hacsak nem adja át TRUE a paramétert az bManualReset építés során.
A manuális CEvent objektumok a másik függvény által SetEvent beállított állapotban ResetEvent maradnak. Manuális CEvent objektum létrehozásához adja át TRUE a paramétert az bManualReset építés során.
Objektum használatához CEvent szükség esetén hozza létre az CEvent objektumot. Adja meg annak az eseménynek a nevét, amelyen várni szeretne, és adja meg azt is, hogy az alkalmazásnak kezdetben a tulajdonosa legyen. Ezután elérheti az eseményt, amikor a konstruktor visszatér. Hívja SetEvent fel az eseményobjektum jelzésére (elérhetővé tétele), majd hívja meg Unlock , ha befejezte az ellenőrzött erőforrás elérését.
Az objektumok használatának CEvent másik módja, ha adattagként egy típusváltozót CEvent ad hozzá a vezérelni kívánt osztályhoz. Az ellenőrzött objektum létrehozása során hívja meg az adattag konstruktorát CEvent , és adja meg, hogy az esemény kezdetben jelezve van-e, és adja meg a kívánt eseményobjektum típusát, az esemény nevét (ha a folyamathatárokon keresztül fogja használni), valamint a kívánt biztonsági attribútumokat.
Ha ilyen módon szeretne hozzáférni egy CEvent objektum által vezérelt erőforráshoz, először hozzon létre egy típusú vagy típusú CMultiLock változót CSingleLock az erőforrás hozzáférési módjában. Ezután hívja meg az Locklock objektum metódusát (például CMultiLock::Lock). Ezen a ponton a szál vagy hozzáférést kap az erőforráshoz, megvárja az erőforrás kiadását és a hozzáférést, vagy megvárja az erőforrás kiadását, időtúllépését, és nem fér hozzá az erőforráshoz. Mindenesetre az erőforrás szálbiztos módon lett elérve. Az erőforrás felszabadításához hívja meg SetEvent az eseményobjektum jelzését, majd használja az Unlocklock objektum metódusát (például ), vagy hagyja, CMultiLock::Unlockhogy az objektum kiessen a lock hatókörből.
Az objektumok használatáról CEvent további információt a Többszálúság: A szinkronizálási osztályok használata című témakörben talál.
Example
// 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
};
Öröklési hierarchia
CEvent
Requirements
Fejléc:afxmt.h
CEvent::CEvent
Névvel ellátott vagy névtelen CEvent objektumot hoz létre.
CEvent(
BOOL bInitiallyOwn = FALSE,
BOOL bManualReset = FALSE,
LPCTSTR lpszName = NULL,
LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);
Paraméterek
bInitiallyOwn
HaTRUE, az objektum vagy CSingleLock az CMultilock objektum szála engedélyezve van. Ellenkező esetben minden olyan szálnak, amely hozzá szeretne férni az erőforráshoz, várnia kell.
bManualReset
Ha TRUEaz eseményobjektum manuális esemény, ellenkező esetben az eseményobjektum automatikus esemény.
lpszName
Az CEvent objektum neve. Meg kell adni, ha az objektumot a folyamathatárok között fogja használni. Ha a név egyezik egy meglévő eseménysel, a konstruktor létrehoz egy új CEvent objektumot, amely az adott név eseményére hivatkozik. Ha a név egyezik egy meglévő szinkronizálási objektummal, amely nem esemény, a konstrukció sikertelen lesz. Ha NULL, a név null értékű lesz.
lpsaAttribute
Az eseményobjektum biztonsági attribútumai. A struktúra teljes leírását a Windows SDK-ban talál SECURITY_ATTRIBUTES .
Megjegyzések
Objektum eléréséhez vagy kiadásához CEvent hozzon létre egy vagy CSingleLock több CMultiLock objektumot, és hívja meg annak és Unlock tagfüggvényeitLock.
Egy objektum állapotának CEvent jelzésre történő módosításához (a szálaknak nem kell várniuk), hívás vagy SetEventPulseEvent. Ha egy CEvent objektum állapotát nem aláírtra szeretné állítani (a szálaknak várniuk kell), hívja meg a hívást ResetEvent.
Fontos
Az CEvent objektum létrehozása után győződjön meg arról, GetLastError hogy a mutex még nem létezik. Ha a mutex váratlanul létezett, az azt jelezheti, hogy egy rogue folyamat guggolódik, és rosszindulatúan kívánja használni a mutexet. Ebben az esetben az ajánlott biztonságtudatos eljárás a fogópont bezárása és folytatása, mintha hiba történt volna az objektum létrehozásakor.
CEvent::PulseEvent
Beállítja az esemény állapotát jelzésre (elérhető), felszabadítja a várakozó szálakat, és automatikusan visszaállítja azt nem aláírtra (nem érhető el).
BOOL PulseEvent();
Visszaadott érték
Nonzero, ha a függvény sikeres volt; egyéb esetben 0.
Megjegyzések
Ha az esemény manuális, az összes várakozási szál felszabadul, az esemény nincs hozzárendelve, és PulseEvent visszakerül. Ha az esemény automatikus, egyetlen szál lesz felszabadítva, az esemény nem hozzárendelt értékre van állítva, és PulseEvent visszaadja.
Ha nem várnak szálak, vagy nem lehet azonnal feloldani a szálakat, PulseEvent az esemény állapotát nem hozzárendelt állapotra állítja, és visszaadja.
PulseEvent A mögöttes Win32 PulseEvent függvényt használja, amely egy kernelmódú aszinkron eljáráshívással azonnal eltávolítható a várakozási állapotból. Ezért megbízhatatlan, PulseEvent és az új alkalmazások nem használhatják. További információkért tekintse meg a függvénytPulseEvent.
CEvent::ResetEvent
Az esemény állapotát nem hozzárendelt állapotra állítja, amíg a SetEvent tagfüggvény explicit módon nem jelzi.
BOOL ResetEvent();
Visszaadott érték
Nonzero, ha a függvény sikeres volt; egyéb esetben 0.
Megjegyzések
Emiatt az eseményhez hozzáférni kívánó összes szál várakozni próbál.
Ezt a tagfüggvényt nem használják automatikus események.
CEvent::SetEvent
Beállítja az esemény állapotát jelzésre, és felszabadítja a várakozó szálakat.
BOOL SetEvent();
Visszaadott érték
Nonzero, ha a függvény sikeres volt, egyébként 0.
Megjegyzések
Ha az esemény manuális, az esemény addig lesz jelezve, amíg meg nem ResetEvent hívják. Ebben az esetben több szál is kibocsátható. Ha az esemény automatikus, az esemény csak egyetlen szál felszabadításáig lesz jelezve. A rendszer ezután az esemény állapotát nem aláírtra állítja. Ha egyetlen szál sem várakozik, az állapot addig lesz jelezve, amíg egy szál fel nem szabadul.
CEvent::Unlock
Felszabadítja az eseményobjektumot.
BOOL Unlock();
Visszaadott érték
Nonzero, ha a szál az eseményobjektum tulajdonosa, és az esemény egy automatikus esemény; egyéb esetben 0.
Megjegyzések
Ezt a tagfüggvényt olyan szálak hívják meg, amelyek jelenleg egy automatikus eseményt birtokolnak, hogy a művelet után felbocsátsák azt, ha az objektumot lock újra fel szeretné használni. Ha az lock objektumot nem szeretné újra felhasználni, ezt a függvényt az lock objektum destruktora hívja meg.