J'ai implémenté un thread-producteur de base thread (thread 1 = producteur, thread 2 = consommateur) en utilisant des threads et des conditions Boost. Je suis coincé dans wait() indéfiniment assez souvent. Je ne peux pas vraiment voir ce qui pourrait être mauvais ici. Ci-dessous quelques pseudo-code:Boost condition de blocage en utilisant wait() dans le code producteur-consommateur
// main class
class Main {
public:
void AddToQueue(...someData...)
{
boost::mutex::scoped_lock lock(m_mutex);
m_queue.push_back(new QueueItem(...someData...));
m_cond.notify_one();
}
void RemoveQueuedItem(...someCond...)
{
// i'm wondering if this could cause the trouble?
boost::mutex::scoped_lock lock(m_mutex);
// erase a item matching condition (some code not shown,
// but should be fairly self-explanatory -- IsMatch()
// simply looks at a flag of QueueItem
m_queue.erase(std::remove_if(m_queue.being(), m_queue.end(),
boost::bind(&Main::IsMatch, this, _1, someCond), m_queue.end());
}
friend void WorkerThread(Main* m);
private:
boost::ptr_deque<QueueItem> m_queue;
boost::mutex m_mutex;
boost::condition m_cond;
};
// worker thread
void WorkerThread(Main* m)
{
typedef boost::ptr_deque<QueueItem>::auto_type RelType;
RelType queueItem;
while(!shutDown) {
{ // begin mutex scope
boost::mutex::scoped_lock lock(m->m_mutex);
while(m->m_queue.empty()) {
m->m_cond.wait(lock); // <- stuck here forever quite often!
}
queueItem = m->m_queue->pop_front(); // pop & take ptr ownership
} // end mutex scope
// ... do stuff with queueItem
// ...
// ... queueItem is deleted when it leaves scope & we loop around
}
}
Quelques informations supplémentaires:
- En utilisant Boost v1.44
- problème se produit dans Linux et Android; Je ne suis pas encore sûr si cela se produit dans Windows
Des idées?
MISE À JOUR: Je crois J'ai isolé la question. Je mettrai à jour plus loin une fois confirmé, qui, espérons-le, sera demain.
MISE À JOUR 2: Il s'avère qu'il n'y a pas de problème dans le code décrit ci-dessus. Je dépendais d'une API sous-jacente pour AddToQueue() - lors du traitement des données dans le thread de travail & le remettant à l'API, il avait un bug circulaire où il appelait AddToQueue() à nouveau ... qui est maintenant corrigé ;-)
Votre code ci-dessus n'a pas la partie où vous attendez le sur la variable conditionnelle. Collez-le aussi. – wilx
Dans mon thread de travail (consommateur) ci-dessus, vous verrez un moment (queue_is_empty()) {cond.wait (lock); } Est-ce ce que vous voulez dire? – NuSkooler