Если вы собираетесь работать с несколькими потоками, трудно избежать синхронизации.К счастью, это не очень сложно.
Для одного процесса критический раздел часто является наилучшим выбором.Это быстрый и простой в использовании.Для простоты я обычно заключаю его в класс для обработки инициализации и очистки.
#include <Windows.h>
class CTkCritSec
{
public:
CTkCritSec(void)
{
::InitializeCriticalSection(&m_critSec);
}
~CTkCritSec(void)
{
::DeleteCriticalSection(&m_critSec);
}
void Lock()
{
::EnterCriticalSection(&m_critSec);
}
void Unlock()
{
::LeaveCriticalSection(&m_critSec);
}
private:
CRITICAL_SECTION m_critSec;
};
Вы можете сделать это еще проще с помощью класса «autolock», который вы блокируете / разблокируете.
class CTkAutoLock
{
public:
CTkAutoLock(CTkCritSec &lock)
: m_lock(lock)
{
m_lock.Lock();
}
virtual ~CTkAutoLock()
{
m_lock.Unlock();
}
private:
CTkCritSec &m_lock;
};
Везде, где вы хотите что-то заблокировать, создайте экземпляр автоматической блокировки.Когда функция завершится, она разблокируется.Кроме того, если есть исключение, оно автоматически разблокируется (обеспечивая безопасность исключений).
Теперь вы можете сделать простую очередь сообщений из очереди с приоритетами std
#include <queue>
#include <deque>
#include <functional>
#include <string>
struct CMsg
{
CMsg(const std::string &s, int n=1)
: sText(s), nPriority(n)
{
}
int nPriority;
std::string sText;
struct Compare : public std::binary_function<bool, const CMsg *, const CMsg *>
{
bool operator () (const CMsg *p0, const CMsg *p1)
{
return p0->nPriority < p1->nPriority;
}
};
};
class CMsgQueue :
private std::priority_queue<CMsg *, std::deque<CMsg *>, CMsg::Compare >
{
public:
void Push(CMsg *pJob)
{
CTkAutoLock lk(m_critSec);
push(pJob);
}
CMsg *Pop()
{
CTkAutoLock lk(m_critSec);
CMsg *pJob(NULL);
if (!Empty())
{
pJob = top();
pop();
}
return pJob;
}
bool Empty()
{
CTkAutoLock lk(m_critSec);
return empty();
}
private:
CTkCritSec m_critSec;
};
СодержимоеCMsg может быть чем угодно.Обратите внимание, что CMsgQue наследует конфиденциально от std :: priority_queue.Это предотвращает необработанный доступ к очереди без использования наших (синхронизированных) методов.
Назначьте подобную очередь каждому потоку, и вы уже в пути.
Отказ от ответственности Код здесь был быстро соединен, чтобы проиллюстрировать точку.Вероятно, он содержит ошибки и требует проверки и тестирования перед использованием в производстве.