2013-04-01 82 views

回答

14

聲稱std::regex在各方面都是線程安全的,這是一個非常大膽的陳述。 C++ 11標準沒有爲正則表達式庫做出這樣的保證。

但是,看看std::regex_search的原型,表明它需要將basic_regex對象作爲常量參數。這意味着它受到標準庫的保證,該函數的const修飾符implies thread-safety與該參數相關。

在standardese,那就是:

[17.6.5.9/1] 該節指定實現中應滿足以防止數據爭要求(1.10)。除非另有說明,否則每個標準庫函數都應符合各項要求在下面指定的情況以外的情況下,實現可能會阻止數據競爭。

[17.6.5.9/3] A C++標準庫函數應不直接或間接地修改對象(1.10)比當前線程其他線程訪問,除非對象通過該函數的非直接或間接地訪問-const參數,包括this

所以,在您使用標準庫的實現禁止的錯誤,看來要std::regex_search調用是線程安全的相對於該傳入的regex對象。


其他的想法:

只是因爲std::regex_search是重入相對於它的regex說法並不意味着你完全露出水面。在線程安全的調用(如std::regex_search)的同時以非線程安全的方式執行修改regex的操作仍然是未定義的行爲。 basic_regexassignment operator,std::swapbasic_regex::imbue想到它們對其操作的basic_regex的非線程安全函數。知道了這一點,對於每個線程閒暇時使用/修改應該以最低的性能成本製作一個regex對象的副本可能會更好。

+0

'std :: regex'實例代表一個已編譯的正則表達式,*意味着*被重用,因爲正則表達式編譯是一個代價高昂的過程。當然,當其他線程已經在使用它時,交換/重新分配一個已存在的實例(無論是'std :: regex'還是其他任何東西)都是愚蠢的。 – rustyx

1

儘管Sean's answer對標準來說是正確的,但個別實施可能會失敗。至少,VC++ 2013看起來好像在它的拷貝構造函數中有一個race conditions,並且在一個懶惰的求值變量中。

+0

根據該票,它應該在最近發佈的VS2015中得到修復。 –