Sto sviluppando un programma con multithreading in esecuzione su Linux (compilato con G ++ 4.3) e se cerchi un po 'trovi un sacco di storie spaventose su std :: string che non è thread-safe con GCC. Ciò è dovuto al fatto che internamente utilizza la copia su scrittura che provoca il caos con strumenti come Helgrind.È std :: string thead-safe con gcc 4.3?
Ho creato un piccolo programma che copia una stringa in un'altra stringa e se si controllano entrambe le stringhe condividono entrambi lo stesso puntatore _M_p interno. Quando una stringa viene modificata, il puntatore cambia in modo che la roba copy-on-write funzioni correttamente.
Ciò che mi preoccupa è che cosa succede se condivido una stringa tra due thread (ad esempio, passandola come un oggetto in un dataqueue thread-safe tra due thread). Ho già provato a compilare con l'opzione '-pthread' ma non sembra fare molta differenza. Quindi la mia domanda:
- C'è un modo per forzare std :: string per essere protetto da thread? Non mi dispiacerebbe se il comportamento copy-on-write fosse disabilitato per raggiungere questo obiettivo.
- Come hanno risolto altre persone? O sono paranoico?
io non riesco a trovare una risposta definitiva quindi spero che voi mi può aiutare ..
Edit:
Wow, questo è un bel po 'di risposte in un così breve tempo. Grazie! Userò sicuramente la soluzione di Jack quando voglio disabilitare COW. Ma ora la domanda principale diventa: devo davvero disabilitare COW? O la 'contabilità' fatta per thread COW è sicura? Attualmente sto navigando le fonti libstdC++, ma che sta andando a prendere un po 'di tempo per capire ...
Edit 2
OK naviga il codice sorgente libstdC++ e ho trovato qualcosa di simile in libstd ++ - v3 /include/bits/basic_string.h:
_CharT*
_M_refcopy() throw()
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
__gnu_cxx::__atomic_add_dispatch(&this->_M_refcount, 1);
return _M_refdata();
} // XXX MT
Quindi c'è sicuramente qualcosa là sulle modifiche atomiche per il contatore di riferimento ...
Conclusione
Sto segnando il commento di sellibitze come risposta qui perché penso che siamo giunti alla conclusione che quest'area non è ancora stata risolta per ora. Per aggirare il comportamento della MUC suggerirei la risposta di Jack Lloyd. Grazie a tutti per una discussione interessante!
+1 buona domanda! Sfortunatamente, la gente legge semplicemente "threadsafe" e pensa "No!". Meglio leggere l'intera domanda! :) – sellibitze
Poiché std :: string è un'istanza del modello std :: basic_string, potrebbe essere possibile dare un'occhiata al codice sorgente. Prova a cercare qualsiasi macro che accenda/spenga la sicurezza del thread. –
A proposito, il copy-on-write è lento negli ambienti multi-thread, dovresti * voler * non usarlo, non essere disposto a farlo. – GManNickG