2012-07-27 3 views
6

Sto usando la coda per la comunicazione tra due thread (uno produce solo un'istanza di una classe personalizzata e spinge il puntatore alla coda, altri letti dal puntatore della coda sulla classe personalizzata e fanno alcuni calcoli). Come rendere push e pop in coda atomica, come bloccare tali operazioni (non posso usare C++ 11 standard)Come rendere push e pop sulla coda atomica, come bloccare quelle operazioni?

risposta

8

Probabilmente il meccanismo di blocco non-C++ 11 più portatile è i tipi synchronisztion della libreria Boost.Thread. In particolare la classe mutex offre un semplice oggetto bloccabile per dare accesso esclusivo a una risorsa. Per esempio:

#include <boost/thread/mutex.hpp> 
#include <queue> 

template <typename T> 
class locking_queue { 
public: 
    void push(T const & value) { 
     boost::mutex::scoped_lock lock(mutex); 
     queue.push(value); 
    } 

    bool pop(T & value) { 
     boost::mutex::scoped_lock lock(mutex); 
     if (queue.empty()) { 
      return false; 
     } else { 
      value = queue.front(); 
      queue.pop(); 
      return true; 
     } 
    } 

private: 
    std::queue<T> queue; 
    boost::mutex mutex; 
}; 

Un altro vantaggio è che questo è molto simile al C++ 11 std::mutex classe, che renderà la conversione abbastanza semplice se si decide di utilizzarlo.

3

Ecco un codice pseudo:?

// Thread A 
mutex.lock(); 
q.push(); 
mutex.unlock(); 

// Thread B 
mutex.lock(); 
q.pop(); 
mutex.unlock(); 

Se stai usando spinta, puoi provare è la classe mutex.

+2

Sebbene si debba sempre usare un blocco con scope in stile RAII, il mutex non rimane bloccato per sempre se 'push' o' pop' lanciano un'eccezione. –

+0

@ MikeSeymour - meh, a chi importa? Se un'operazione semplice come push/pop da una coda può generare un'eccezione, l'app è comunque in materiale deep brown :( –