2013-04-01 13 views

Antwort

14

Die Behauptung, dass std::regex in jeder Hinsicht Thread-Safe ist, ist eine ziemlich kühne Aussage. Der C++ 11-Standard gibt solche Garantien für die Regex-Bibliothek nicht.

Allerdings zeigt der Blick auf den Prototyp std::regex_search, dass es das basic_regex Objekt als ein const Argument benötigt. Dies bedeutet, dass es durch die Garantie der Standardbibliothek geschützt ist, dass der const-Modifikator implies thread-safety der Funktion in Bezug auf dieses Argument ist.

In standardese, das heißt:

[17.6.5.9/1] Dieser Abschnitt legt Anforderungen erfüllen, dass Implementierungen werden die Daten gespeichert Rennen (1,10) zu verhindern. Jede Standardbibliotheksfunktion muss jede Anforderung erfüllen, sofern nicht anders angegeben. Implementierungen können Datenrennen in anderen als den unten angegebenen Fällen verhindern.

[17.6.5.9/3] Standardbibliotheksfunktion ++ A C wird nicht direkt oder indirekt Objekte ändern (1,10) zugänglich durch Fäden anderer als der aktuelle Thread, es sei denn die Gegenstände nicht direkt oder indirekt über die Funktion des zugegriffen -const Argumente, einschließlich this.

Also, einen Fehler in der Implementierung der Standardbibliothek Sperre, die Sie verwenden, scheint es, dass Anrufe an std::regex_search Thread-sicher sind in Bezug auf das regex Objekt, das in übergeben wird.


Andere Gedanken:

Nur weil std::regex_search ist einspringenden in Bezug auf sein regex Argument bedeutet nicht, dass Sie vollständig aus dem Wasser. Das Ausführen einer Operation, die eine regex auf nicht threadsichere Weise gleichzeitig mit einem threadsicheren Aufruf wie std::regex_search ändert, ist immer noch undefiniert. basic_regex 's assignment operator, std::swap und basic_regex::imbue kommen als nicht-Thread-sichere Funktionen in Bezug auf die basic_regex sie arbeiten auf. Wenn Sie dies wissen, ist es möglicherweise besser, eine Kopie des Objekts regex zu erstellen, das zu minimalen Kosten für die Leistung führen sollte.

+0

'std :: regex'-Instanzen stellen einen kompilierten regulären Ausdruck dar und sind * gemeint *, um wiederverwendet zu werden, da die Regex-Kompilierung ein kostspieliger Prozess ist. Natürlich wäre es blöd, eine existierende Instanz (sei es 'std :: regex' oder irgendetwas anderes) zu tauschen/neu zuzuordnen, während andere Threads sie bereits benutzen. – rustyx

1

Während Sean's answer für den Standard gilt, kann die individuelle Implementierung zu kurz greifen. Zumindest sieht VC++ 2013 so aus, als hätte es race conditions in seinem Kopierkonstruktor und in einer faul bewerteten Variablen.

+0

Nach diesem Ticket sollte es in der kürzlich veröffentlichten VS2015 behoben werden. –