У меня есть один случай событийный класс, который имеет очередь и поток на нем. Реализация подобна реализации, существует несколько модулей/объектов, которые подписываются на определенные события и могут отправлять несколько событий.критический раздел для очереди внутри потока
Цель этого класса событий - получить все эти события, нажав их на очередь, и поток внутри этого класса должен заполнить событие и отправить его соответствующим соответствующим подписным модулям/объектам.
Идея создания C++ базы EventAggregator, доступной на C#.
Реализация подобно
void c_eventAggregator::PostEvent(EVENT_UID EventUid)
{
c_criticalRegion criticalRegion(eASyncObj);
Queue.push_back(EventUid);
criticalRegion.~c_criticalRegion();
}
void c_eventAggregator::DispatchEventToClients(EVENT_UID EventUid)
{
EventClientsList eclist = _eventIdSubsList[EventUid];
for (EventClientsList::iterator iter = eclist.begin(); iter != eclist.end(); iter++) {
iter->second->receiveEvent(EventUid);
}
}
int c_eventAggregator::SubscribeEvent(EVENT_CLIENTID clientId, c_eventClient *ecPtr, EVENT_UID EventUid)
{
try
{
_eventIdSubsList[EventUid].insert(make_pair(clientId, ecPtr));
}
catch (int exception)
{
return exception;
}
return ZERO_VALUE;
}
void c_eventAggregator::run(void)
{
EVENT_UID EventUid;
while (isAlive())
{
while (Queue.size())
{
if (!Queue.empty())
{
c_criticalRegion criticalRegion(eASyncObj);
EventUid = Queue[0];
Queue.pop_front();
DispatchEventToClients(EventUid);
criticalRegion.~c_criticalRegion();
}
}
}
}
Я использую критической секции между нажатием и поп-музыки, так что очередь не перезаписываются, если несколько модулей/объект записи одновременно. (Не уверен, что это правильно).
Мой критический обработчик раздел как
class c_criticalRegion{
public:
c_criticalRegion(c_syncObject &paSyncObject) : mSyncObject(paSyncObject){
mSyncObject.lock();
}
~c_criticalRegion(){
mSyncObject.unlock();
}
private:
c_syncObject &mSyncObject;
};
объект синхронизации, как sync.cpp,
c_syncObject::c_syncObject(){
InitializeCriticalSection(&m_oMutexHandle);
}
c_syncObject::~c_syncObject(){
DeleteCriticalSection(&m_oMutexHandle);
}
synch.h:
class c_syncObject{
private:
protected:
//! The win32 CRITICAL_SECTION handle of the operating system.
CRITICAL_SECTION m_oMutexHandle;
public:
c_syncObject();
~c_syncObject();
/*!\brief Lock the resource coming after the lock command
*
* This function blocks until it will get the lock for the coming critical section.
*/
void lock(void){
EnterCriticalSection(&m_oMutexHandle);
//TODO handle return value
};
//!Free the resource coming after the lock command
void unlock(void){
LeaveCriticalSection(&m_oMutexHandle);
//TODO handle return value
};
};
Issue я сталкиваюсь здесь код не работает, если я не прокомментирую criticalRegion.~c_criticalRegion()
внутри PostEven t(). Аналогично, когда есть событие, отправьте на PostEvent, очередь внутри run()
по-прежнему показывает размер как ноль.
Это вроде тривиально, когда я получаю такую же ситуацию и в других файлах, которые имеют аналогичный вид реализации.
Также я хотел бы знать, когда выпуск критической секции, после завершения задачи DispatchEventToClients()
или раньше.
Кстати, я не знаю вашего варианта использования, но в общем вы должны обернуть 'SubscribeEvent' с критической секции тоже. Если случай кто-то вызывает его во время 'DispatchEventToClients'. –
Вы не должны называть 'criticalRegion. ~ C_criticalRegion()' в 'PostEvent' и' run' вообще.Он будет вызываться автоматически, когда программа выходит из области действия. В вашем случае это называется дважды. –
@MichaelNastenko: Я тебя не понимаю. Вы хотите сказать, не нужно освобождать замок? Если да, то как он понимает длину критической области – kar