2013-04-01 2 views

risposta

14

Affermare che std::regex è thread-safe in ogni senso è una dichiarazione piuttosto audace. Lo standard C++ 11 non fornisce tali garanzie per la libreria regex.

Tuttavia, guardando il prototipo di std::regex_search mostra che ci vuole l'oggetto basic_regex come argomento const. Ciò significa che è protetto dalla garanzia della libreria standard che il modificatore const implies thread-safety della funzione rispetto a tale argomento.

nello standard, cioè:

[17.6.5.9/1] Questa sezione specifica i requisiti che le implementazioni devono soddisfare per evitare corse di dati (1.10). Ogni funzione di libreria standard deve soddisfare ogni requisito, se non diversamente specificato. Le implementazioni possono impedire le corse di dati in casi diversi da quelli specificati di seguito.

[17.6.5.9/3] A C++ funzione della libreria standard non deve direttamente o indirettamente modificare gli oggetti (1,10) accessibile da fili diversi thread corrente meno che gli oggetti sono accessibili direttamente o indirettamente tramite della funzione non -const argomenti, incluso this.

Quindi, a meno di un bug nell'implementazione della libreria standard che si utilizza, sembra che le chiamate verso std::regex_search sono thread-safe con rispetto all'oggetto regex che viene passato.


Altri pensieri:

Solo perché std::regex_search è rientrante rispetto al suo argomento regex non significa che siete completamente fuori dall'acqua. L'esecuzione di un'operazione che modifica uno regex in modo non thread-thread contemporaneamente a una chiamata thread-safe come std::regex_search è ancora un comportamento non definito. basic_regex 's assignment operator, std::swap e basic_regex::imbue vengono in mente come funzioni non thread-safe rispetto al basic_regex su cui operano. Sapendo questo, potrebbe essere meglio fare una copia dell'oggetto regex, che dovrebbe avere un costo di prestazioni minimo, per ogni thread da utilizzare/modificare a suo piacimento.

+0

Le istanze 'std :: regex' rappresentano un'espressione regolare compilata e sono * destinate * per essere riutilizzate, poiché la compilazione di espressioni regolari è un processo costoso. Ovviamente sarebbe stupido scambiare/riassegnare un'istanza esistente (sia esso 'std :: regex' o qualsiasi altra cosa) mentre altri thread lo stanno già utilizzando. – rustyx

1

Mentre Sean's answer è conforme allo standard, l'implementazione individuale potrebbe non essere sufficiente. VC++ 2013, almeno, sembra che abbia race conditions nel suo costruttore di copie e in una variabile valutata pigramente.

+0

Secondo questo ticket, dovrebbe essere corretto nel VS2015 rilasciato di recente. –