2012-10-09 19 views
17

Estoy en el proceso de transferir algún código de Java a C++, y una sección en particular utiliza un BlockingQueue para pasar mensajes de muchos productores a un solo consumidor.C++ Equivalente a BlockingQueue de Java

Si no está familiarizado con lo que es una Java BlockingQueue, es solo una cola que tiene una capacidad difícil, que expone los métodos de seguridad de subprocesos put() y take() de la cola. put() bloques si la cola está llena, y take() bloques si la cola está vacía. Además, se suministran versiones sensibles al tiempo de espera de estos métodos.

Los tiempos de espera son relevantes para mi caso de uso, por lo que una recomendación que los suministre es ideal. Si no, puedo codificar yo mismo.

He buscado en Google y navegué rápidamente por las bibliotecas de Boost y no encuentro nada como esto. Tal vez estoy ciego aquí ... pero ¿alguien sabe de una buena recomendación?

Gracias!

+0

clase hecha a mano que tiene una matriz (tal vez deque en lugar de matriz para pop_front push_back más fácil) y mutex? – NoSenseEtAl

+0

¿es la capacidad dura realmente un requisito? –

+1

En mi caso, sí. Es muy posible que los productores superen a los consumidores, y tengo la necesidad de bloquear los hilos del lado del productor, o rechazar su entrada, por temor a que se me acabe la memoria. – Ben

Respuesta

32

No se fija tamaño y no es compatible con los tiempos de espera, pero aquí es una sencilla aplicación de una cola que había publicado recientemente usando C++ 2011: construcciones

#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; 
    } 
}; 

Debe ser trivial para extender y uso una espera cronometrada para estallar. La razón principal por la que no lo hice es porque no estoy contento con las opciones de interfaz en las que he pensado hasta ahora.

+0

es el alcance en el empuje necesario? Supongo que estás intentando desbloquear el mutex ... pero no estoy seguro de los requisitos previos para notify_one. – NoSenseEtAl

+8

El alcance en 'push()' no es necesario, pero sin él la variable de condición se señaliza mientras el bloqueo aún se mantiene. Al soltar la cerradura antes de la señalización, la cerradura está disponible. –

+0

¿Alguien podría ampliar este ejemplo para 'espera temporizada para estallar''? – javapowered