CEvent
Sınıf
Bir iş parçacığının başka bir iş parçacığının bir olayın gerçekleştiğini bildirmesini sağlayan bir eşitleme nesnesi olan bir olayı temsil eder.
Sözdizimi
class CEvent : public CSyncObject
Üyeler
Ortak Oluşturucular
Veri Akışı Adı | Açıklama |
---|---|
CEvent::CEvent |
Bir CEvent nesne oluşturur. |
Genel Yöntemler
Veri Akışı Adı | Açıklama |
---|---|
CEvent::PulseEvent |
Olayı kullanılabilir (sinyalli) olarak ayarlar, bekleyen iş parçacıklarını serbest bırakır ve olayı kullanılamaz (işaretsiz) olarak ayarlar. |
CEvent::ResetEvent |
Olayı kullanılamaz (işaretsiz) olarak ayarlar. |
CEvent::SetEvent |
Olayı kullanılabilir (sinyalli) olarak ayarlar ve bekleyen iş parçacıklarını serbest bırakır. |
CEvent::Unlock |
Olay nesnesini serbest bırakır. |
Açıklamalar
Bir iş parçacığının görevini ne zaman gerçekleştirmesi gerektiğini bilmesi gerektiğinde olaylar yararlıdır. Örneğin, veri arşivine veri kopyalayan bir iş parçacığı, yeni veriler kullanılabilir olduğunda bildirilmelidir. Yeni veriler kullanılabilir olduğunda kopya iş parçacığını bilgilendirmek için bir CEvent
nesne kullanarak, iş parçacığı görevini en kısa sürede gerçekleştirebilir.
CEvent
nesnelerin iki türü vardır: el ile ve otomatik.
CEvent
Otomatik nesne, en az bir iş parçacığı serbest bırakıldıktan sonra otomatik olarak sinyalsiz (kullanılamaz) duruma döner. Varsayılan olarak, oluşturma sırasında parametresini bManualReset
geçirmediğiniz TRUE
sürece nesne CEvent
otomatiktir.
El ile CEvent
bir nesne, diğer işlev çağrılana kadar veya ResetEvent
tarafından SetEvent
ayarlanan durumda kalır. El ile CEvent
nesne oluşturmak için, oluşturma sırasında parametresini bManualReset
geçirinTRUE
.
Bir CEvent
nesneyi kullanmak için gerekli olduğunda nesnesini oluştur CEvent
. Beklemek istediğiniz olayın adını belirtin ve ayrıca uygulamanızın başlangıçta buna sahip olması gerektiğini belirtin. Ardından oluşturucu döndürdüğünde olaya erişebilirsiniz. Olay nesnesini sinyale çağırın SetEvent
(kullanılabilir duruma getirin) ve ardından denetimli kaynağa erişiminizi bitirdiğinizde çağırın Unlock
.
Nesneleri kullanmanın CEvent
alternatif bir yöntemi, denetlemek istediğiniz sınıfa veri üyesi olarak türünde CEvent
bir değişken eklemektir. Denetimli nesnenin oluşturulması sırasında, veri üyesinin oluşturucusunu CEvent
çağırın ve olayın başlangıçta işaretlenip işaretlenmediğini belirtin ve ayrıca istediğiniz olay nesnesi türünü, olayın adını (işlem sınırları boyunca kullanılacaksa) ve istediğiniz güvenlik özniteliklerini belirtin.
Nesne tarafından denetlenen bir CEvent
kaynağa bu şekilde erişmek için, önce kaynağınızın erişim yönteminde türünde CSingleLock
veya türünde CMultiLock
bir değişken oluşturun. Ardından nesnesinin Lock
yöntemini çağırın lock
(örneğin, CMultiLock::Lock
). Bu noktada iş parçacığınız kaynağa erişim elde eder, kaynağın serbest bırakılıp erişim kazanmasını bekler veya kaynağın yayımlanmasını, zaman aşımına uğradırmasını ve kaynağa erişememesini bekler. Her durumda kaynağınıza iş parçacığı açısından güvenli bir şekilde erişilmiştir. Kaynağı serbest bırakmak için olay nesnesine sinyal gönderme çağrısı SetEvent
yapın ve nesnenin lock
yöntemini (örneğin, CMultiLock::Unlock
) kullanın Unlock
veya nesnenin lock
kapsamın dışına çıkmasını sağlayın.
Nesneleri kullanma CEvent
hakkında daha fazla bilgi için bkz . Çoklu İş Parçacığı Kullanımı: Eşitleme Sınıflarını Kullanma.
Örnek
// 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
};
Devralma Hiyerarşisi
CEvent
Gereksinimler
Üstbilgi: afxmt.h
CEvent::CEvent
Adlandırılmış veya adlandırılmamış CEvent
bir nesne oluşturur.
CEvent(
BOOL bInitiallyOwn = FALSE,
BOOL bManualReset = FALSE,
LPCTSTR lpszName = NULL,
LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);
Parametreler
bInitiallyOwn
iseTRUE
, veya CSingleLock
nesnesi için CMultilock
iş parçacığı etkinleştirilir. Aksi takdirde, kaynağa erişmek isteyen tüm iş parçacıklarının beklemesi gerekir.
bManualReset
ise TRUE
, olay nesnesinin el ile gerçekleştirilen bir olay olduğunu belirtir, aksi takdirde olay nesnesi otomatik bir olaydır.
lpszName
Nesnenin CEvent
adı. Nesne işlem sınırları boyunca kullanılacaksa sağlanmalıdır. Ad mevcut bir olayla eşleşiyorsa, oluşturucu bu adın olayına başvuran yeni CEvent
bir nesne oluşturur. Ad, olay olmayan mevcut bir eşitleme nesnesiyle eşleşiyorsa, yapı başarısız olur. ise NULL
, ad null olur.
lpsaAttribute
Olay nesnesi için güvenlik öznitelikleri. Bu yapının tam açıklaması için Bkz SECURITY_ATTRIBUTES
. Windows SDK'sı.
Açıklamalar
Bir CEvent
nesneye erişmek veya nesneyi serbest bırakmak için bir CMultiLock
veya CSingleLock
nesnesi oluşturun ve nesnenin ve Unlock
üye işlevlerini çağırinLock
.
Bir CEvent
nesnenin durumunu sinyalli olarak değiştirmek için (iş parçacıklarının beklemesi gerekmez), veya PulseEvent
çağrısı SetEvent
yapın. Bir CEvent
nesnenin durumunu işaretsiz olarak ayarlamak için (iş parçacıkları beklemelidir), çağrısı yapın ResetEvent
.
Önemli
Nesnesini oluşturduktan CEvent
sonra mutex'in mevcut olmadığından emin olmak için kullanın GetLastError
. Mutex beklenmedik bir şekilde mevcutsa, sahte bir işlemin çömeldiğini ve mutex'i kötü amaçlı olarak kullanmayı amaçladığını gösterebilir. Bu durumda, önerilen güvenlik bilincine sahip yordam tanıtıcıyı kapatmak ve nesne oluşturulurken bir hata varmış gibi devam etmektir.
CEvent::PulseEvent
Olayın durumunu işaretlendi (kullanılabilir) olarak ayarlar, bekleyen tüm iş parçacıklarını serbest bırakır ve otomatik olarak işaretsiz (kullanılamaz) olarak sıfırlar.
BOOL PulseEvent();
Dönüş Değeri
İşlev başarılı olursa sıfır olmayan; aksi takdirde 0.
Açıklamalar
Olay el ile ise, tüm bekleyen iş parçacıkları serbest bırakılır, olay işaretsiz olarak ayarlanır ve PulseEvent
döndürür. Olay otomatikse, tek bir iş parçacığı serbest bırakılır, olay işaretsiz olarak ayarlanır ve PulseEvent
döndürür.
Bekleyen iş parçacığı yoksa veya hiçbir iş parçacığı hemen serbest bırakılamıyorsa, PulseEvent
olayın durumunu işaretsiz olarak ayarlar ve döndürür.
PulseEvent
temel alınan Win32 PulseEvent
işlevini kullanır. Bu işlev, çekirdek modu zaman uyumsuz yordam çağrısı tarafından bekleme durumundan anlık olarak kaldırılabilir. Bu nedenle güvenilir PulseEvent
değildir ve yeni uygulamalar tarafından kullanılmamalıdır. Daha fazla bilgi için işlevine PulseEvent
bakın.
CEvent::ResetEvent
Üye işlevi tarafından SetEvent
açıkça işaretlenmek üzere ayarlanana kadar olayın durumunu işaretsiz olarak ayarlar.
BOOL ResetEvent();
Dönüş Değeri
İşlev başarılı olursa sıfır olmayan; aksi takdirde 0.
Açıklamalar
Bu, bu olaya erişmek isteyen tüm iş parçacıklarının beklemesine neden olur.
Bu üye işlevi otomatik olaylar tarafından kullanılmaz.
CEvent::SetEvent
Bekleyen iş parçacıklarını serbest bırakarak olayın durumunu işaretlendi olarak ayarlar.
BOOL SetEvent();
Dönüş Değeri
İşlev başarılı olursa sıfır olmayan, aksi takdirde 0.
Açıklamalar
Olay el ile ise, çağrılana kadar ResetEvent
olay sinyalli kalır. Bu durumda birden fazla iş parçacığı serbest bırakılabilir. Olay otomatikse, tek bir iş parçacığı serbest bırakılana kadar olay sinyalli kalır. Sistem daha sonra olayın durumunu işaretsiz olarak ayarlar. Bekleyen iş parçacığı yoksa, bir iş parçacığı serbest bırakılana kadar durum sinyalli kalır.
CEvent::Unlock
Olay nesnesini serbest bırakır.
BOOL Unlock();
Dönüş Değeri
İş parçacığı olay nesnesine sahipse ve olay otomatik bir olaysa sıfır olmayan; aksi takdirde 0.
Açıklamalar
Bu üye işlevi, şu anda otomatik bir olaya sahip olan iş parçacıkları tarafından çağrılır ve nesnesi yeniden kullanılacaksa lock
, tamamlandıktan sonra serbest bırakır. lock
Nesne yeniden kullanılamazsa, bu işlev nesnenin lock
yıkıcısı tarafından çağrılır.