2012-10-09 12 views
17

Sono in procinto di eseguire il porting di un codice Java su C++ e una sezione specifica utilizza un BlockingQueue per passare messaggi da molti produttori a un singolo utente.C++ Equivalente a Java's BlockingQueue

Se non si ha familiarità con cosa sia un Java BlockingQueue, è solo una coda con una capacità difficile, che espone metodi thread-safe da put() e take() dalla coda. put() blocca se la coda è piena e take() blocca se la coda è vuota. Inoltre, vengono fornite versioni sensibili a timeout di questi metodi.

I timeout sono rilevanti per il mio caso d'uso, quindi una raccomandazione che li fornisce è l'ideale. In caso contrario, posso indicizzarne qualcuno.

Ho cercato su Google e rapidamente ho sfogliato le librerie Boost e non trovo nulla di simile. Forse sono cieco qui ... ma qualcuno sa di una buona raccomandazione?

Grazie!

+0

classe fatta a mano che ha un array (forse deque invece di array per facilitare pop_front push_back) e mutex? – NoSenseEtAl

+0

è davvero una grande capacità? –

+1

Nel mio caso, sì. È molto probabile che i produttori superino i consumatori e io abbia la necessità di bloccare i thread dal lato del produttore, o altrimenti di rifiutare il loro input, per paura che finisca la memoria! – Ben

risposta

32

E non è fisso dimensioni e non supporta i timeout, ma qui è una semplice implementazione di una coda che avevo postato di recente utilizzando C++ 2011 costrutti:

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

Dovrebbe essere banale per estendere e l'uso un'attesa a tempo per scoppiare. Il motivo principale per cui non l'ho fatto è che non sono soddisfatto delle scelte di interfaccia che ho pensato finora.

+0

è l'ambito in push necessario? Immagino tu stia cercando di sbloccare il mutex ... ma non sono sicuro dei prerequisiti per notify_one. – NoSenseEtAl

+8

L'ambito in 'push()' non è necessario ma senza di esso la variabile di condizione viene segnalata mentre il blocco è ancora in attesa. Rilasciando il lucchetto prima della segnalazione, la serratura è immediatamente disponibile. –

+0

qualcuno potrebbe estendere questo esempio per "attesa temporizzata per lo scoppiettio"? – javapowered