2013-07-03 11 views
10

Sto provando a inserire std::string in boost::lockfree::queue s in modo che i miei thread possano aggiornarsi a vicenda con nuovi dati.come mettere std :: string in boost :: lockfree :: queue (o alternativo)?

Quando provo ad usare boost::lockfree::queue<std::string> updated_data;, g++ dice:

In instantiation of 'class boost::lockfree::queue >':

error: static assertion failed: (boost::has_trivial_destructor::value)

error: static assertion failed: (boost::has_trivial_assign::value)

Sono stato shown generally what these errors mean, ma non ho alcuna speranza di fissare questo me stesso, come io sono quasi nuovo di zecca a C++.

Esiste un modo alternativo per passare i dati di testo tra i thread con lockfree? In caso contrario, mostrami come inserire std::string in un boost::lockfree::queue.

risposta

2

Se si mettono puntatori grezzi nella coda, il vecchio std::strings verrà divulgato, poiché non è possibile liberarli quando non sono più necessari. Questo perché non c'è modo di liberare gli oggetti in modo thread-safe senza prendere un lucchetto (tranne alcuni trucchi come indicatori di pericolo, che non usa boost::lockfree::queue)

Per motivi tecnici, non capisco, il boost::lockfree::queue richiede un operatore di assegnazione banale e un distruttore banale, il che significa che il tuo oggetto non può essere né contenere alcun tipo di dati che deve liberare memoria nel suo distruttore, come std::string.

+2

Questo non è proprio vero: puoi mettere i puntatori grezzi in coda e liberarli quando fai il puntatore. pe 'queue-> consume_all ([] (std :: string * str) {do_something (str); delete str;});' – Zero

10

La documentazione boost::lockfree::queue indica chiaramente che l'itemm contenuto deve avere un'assegnazione e un distruttore di copia banale, che non è presente in std::string.

Se si dispone di un singolo produttore e di un singolo consumatore, è possibile utilizzare spsc_queue (http://www.boost.org/doc/libs/1_54_0/doc/html/boost/lockfree/spsc_queue.html) che richiede solo la costruibilità e la riproducibilità predefinite.

Se si dispone di più produttori o consumatori, si verrà bloccati con una normale coda di blocco (o una stringa personalizzata che non utilizza l'allocazione dinamica).

+0

Grazie, ottimo a capo dello spsc_queue! – Austin

8

I have no hope of ever fixing this myself, as I'm almost brand new to c++.

Quindi devo chiedermi perché stai scherzando con cose come code senza serratura.

Is there an alternative way to pass text data between threads with lockfree ?

Sì, si può solo memorizzare un puntatore std::string* ai dati nella coda, perché un puntatore è un tipo banale e così è consentita nella coda. Equivalentemente, è possibile memorizzare un reference_wrapper<std::string>. Il problema è che hai bisogno di memorizzare le stringhe da qualche altra parte, in modo da essere in grado di indicarle, quindi ora tutto ciò che hai fatto è spostare il problema da qualche altra parte (ad esempio potresti mantenere un elenco di stringhe in ogni thread e memorizza i puntatori alla stringa gestita esternamente nella coda bloccata, ma non si sa quando è sicuro rimuovere uno string dall'elenco per-thread in modo che cresca e cresca.)

Vorrei suggerire si utilizza un semplice std::queue<std::string> e si esegue la sincronizzazione con uno boost::mutex e boost::condition_variable oppure si trova un'implementazione esistente di una coda thread-safe (non bloccata!).

+0

Questo ottiene +1 perché non ho nemmeno considerato di memorizzare i puntatori raw nella coda. –

+0

Fai già cosa, memorizza i puntatori grezzi? Dove metterebbe gli oggetti reali?In generale, è una cattiva pratica mettere dei puntatori grezzi non gestiti in contenitori, è troppo facile perdere memoria. –

+0

Beh, ecco qua, hai risolto il problema, ora è solo una [semplice questione di programmazione] (http: //www.catb .org/jargon/html/S/SMOP.html);) –