Je suis en train de porter du code Java sur C++, et une section particulière utilise une file d'attente BlockingQueue pour transmettre les messages de nombreux producteurs à un seul consommateur.
Si vous n'êtes pas familier avec ce qu'est une Java BlockingQueue, il s'agit simplement d'une file d'attente ayant une capacité matérielle, qui expose les méthodes thread-safe à mettre () et à prendre () dans la file d'attente. put () bloque si la file est pleine, et take () bloque si la file est vide. Des versions sensibles à la temporisation de ces méthodes sont également fournies.
Les délais d'attente sont pertinents pour mon cas d'utilisation, donc une recommandation qui les fournit est idéale. Sinon, je peux en coder moi-même.
J'ai cherché sur Google et parcouru rapidement les bibliothèques Boost et je ne trouve rien de tel. Peut-être que je suis aveugle ici ... mais est-ce que quelqu'un connaît une bonne recommandation?
Merci!
Sa taille n'est pas fixe et ne prend pas en charge les délais, mais voici une implémentation simple d'une file d'attente que j'avais postée récemment à l'aide de constructions C++ 2011:
#include <mutex>
#include <condition_variable>
#include <deque>
template <typename T>
class queue
{
private:
std::mutex d_mutex;
std::condition_variable d_condition;
std::deque<T> d_queue;
public:
void Push(T const& value) {
{
std::unique_lock<std::mutex> lock(this->d_mutex);
d_queue.Push_front(value);
}
this->d_condition.notify_one();
}
T pop() {
std::unique_lock<std::mutex> lock(this->d_mutex);
this->d_condition.wait(lock, [=]{ return !this->d_queue.empty(); });
T rc(std::move(this->d_queue.back()));
this->d_queue.pop_back();
return rc;
}
};
Il devrait être trivial d'étendre et d'utiliser une attente chronométrée pour le popping. La principale raison pour laquelle je ne l'ai pas fait est que je ne suis pas satisfait des choix d'interface auxquels j'ai pensé jusqu'à présent.
Voici un exemple d'une file d'attente de blocage avec demande d'arrêt feature:
template <typename T> class BlockingQueue {
std::condition_variable _cvCanPop;
std::mutex _sync;
std::queue<T> _qu;
bool _bShutdown = false;
public:
void Push(const T& item)
{
{
std::unique_lock<std::mutex> lock(_sync);
_qu.Push(item);
}
_cvCanPop.notify_one();
}
void RequestShutdown() {
{
std::unique_lock<std::mutex> lock(_sync);
_bShutdown = true;
}
_cvCanPop.notify_all();
}
bool Pop(T &item) {
std::unique_lock<std::mutex> lock(_sync);
for (;;) {
if (_qu.empty()) {
if (_bShutdown) {
return false;
}
}
else {
break;
}
_cvCanPop.wait(lock);
}
item = std::move(_qu.front());
_qu.pop();
return true;
}
};
BlockingCollection est une classe de collection sécurisée pour les threads C++ 11 qui est modélisée d'après la classe .NET BlockingCollection.
Il prend en charge les éléments suivants: