Si vous envisagez d'utiliser plusieurs threads, il est difficile d'éviter la synchronisation. Heureusement, ce n'est pas très dur.
Pour un seul processus, une section critique est souvent le meilleur choix. C'est rapide et facile à utiliser. Pour la simplicité, je l'enveloppe normalement dans une classe pour gérer l'initialisation et le nettoyage.
#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;
};
Vous pouvez encore plus simple faire en utilisant une classe « verrouillage automatique » vous verrouillez/déverrouiller.
class CTkAutoLock
{
public:
CTkAutoLock(CTkCritSec &lock)
: m_lock(lock)
{
m_lock.Lock();
}
virtual ~CTkAutoLock()
{
m_lock.Unlock();
}
private:
CTkCritSec &m_lock;
};
Partout où vous voulez verrouiller quelque chose, instanciez un autolock. Lorsque la fonction se termine, elle se déverrouille. En outre, s'il y a une exception, il se déverrouillera automatiquement (donnant une sécurité d'exception).
Maintenant, vous pouvez faire une file d'attente simple message d'une file d'attente prioritaire 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;
};
Le contenu de cmsg peut être tout ce que vous aimez. Notez que le CMsgQue hérite en privé de std :: priority_queue. Cela empêche l'accès brut à la file d'attente sans passer par nos méthodes (synchronisées).
Attribuez une file d'attente comme celle-ci à chaque thread et vous êtes sur votre chemin.
Clause de non-responsabilité Le code ici a été collé rapidement pour illustrer un point. Il a probablement des erreurs et doit être examiné et testé avant d'être utilisé en production.
Merci Nikolaï :) – IamIC