2012-06-20 17 views
26
boost::posix_time::ptime parseDate(const std::string& format, const std::string& localDate) 
{ 
    std::istringstream is(localDate); 
    is.imbue(std::locale(is.getloc(), new boost::local_time::local_time_input_facet(format.c_str()))); 
    boost::posix_time::ptime pt; 
    is >> pt; 

    if (pt == boost::posix_time::ptime()) 
    { 
     throw std::runtime_error("Parse error"); 
    } 

    return pt; 
} 

Questa funzione deve richiedere una data e una stringa di formato e return boost::posix_time::ptime.C++ Perché la mia analisi delle date non è protetta da thread?

E.g .: 2012:06:14 02:50:58 e %Y:%m:%d %H:%M:%S.

Tuttavia, se lo chiamo in un programma multithread, a volte viene generata l'eccezione, anche se format e localDate sono corretti e analizzabili (io uso la stessa data per ogni chiamata). Ho trovato qualcosa su std::stringstream/std::locale problemi di thread ma nulla di aggiornato (sto usando gcc 4.6.3 64 bit).

Here qualcuno ha lo stesso problema:

test nel corso degli ultimi giorni utilizzando Valgrind/DRD, ho trovato molte parti del mio codice che causano problemi. Ad esempio, quando si chiamano alcune funzioni di conversione di data e ora di boost, premo std :: locale(), che non è protetto da thread.

codice aggiornato che non dà problemi:

boost::posix_time::ptime parseDate(const std::string& format, const std::string& localDate) 
{ 
    std::istringstream is(localDate); 
    auto* facet = new boost::local_time::local_time_input_facet(format.c_str()); 

    { 
     boost::unique_lock<boost::mutex> lock(globalLocaleMutex); 
     is.imbue(std::locale(is.getloc(), facet)); 
    } 

    boost::posix_time::ptime pt; 
    is >> pt; 

    if (pt == boost::posix_time::ptime()) 
    { 
     throw std::runtime_error("Parse error"); 
    } 

    return pt; 
} 

Ma ancora: perché?

+0

Che eccezione? – ronag

+0

'throw std :: runtime_error (" Parse error ");' – tauran

+1

Stai usando una libreria runtime con multithreading? VisualStudio per esempio ha due: un singolo thread e multi thread. –

risposta

1

Vedo che c'è una chiamata a local_time. Non sono sicuro se il codice sottostante chiama localtime o localtime_r. Se chiama localtime, non è thread-safe. Credo che localtime usi una variabile statica quando restituisce il risultato.