System.RegularExpressions.TRegEx 是线程安全的吗?

Is System.RegularExpressions.TRegEx thread-safe?

背景:我遇到的一个应用程序使用来自多个线程的TRegEx单例。单例在 class 构造函数中初始化为 TRegEx.Create(Pattern, [roCompiled]),线程从 RegEx.Match(Value).Groups 开始使用它,似乎没有使用同步机制,但是应用程序运行良好。不过,这只是 TThread.Execute 覆盖的一小部分,线程上的负载很小。所以这总是可能只是偶然起作用,因为线程不太可能在关键部分相互交叉。

想法:一方面,考虑一下,TRegEx 实例只包含一个不可变(已编译)模式并继续工作是有道理的直接输入参数,或者将此输入保留在 (TMatch) return 值中,以便以后可能继续使用——例如 NextMatch,这是在 TMatch 上实现的而不是 TRegEx。和 the underlying open source PCRE library seems to be thread-safe。这一切都符合上面的场景。另一方面,我认为 TRegEx 实例通常不是线程安全的,因为例如,在 function TRegEx.Match(const Input: String): TMatch (如上所用)中,看起来要与模式匹配的字符串是第一个在匹配之前存储到实例中。并且相同的嵌套 TPerlRegEx 实例在各种函数链中传递并保持活动状态。一个共享的 TRegEx 实例似乎需要保护免受不协调的访问,例如,一个关键部分。

就是说,我怀疑 TRegEx 不是线程安全的,但我想请教多线程和判断线程安全方面的知识的人进行确认。因此,我的问题——非常笼统并且独立于它从中演变而来的应用程序:

问题:TRegEx 是线程安全的吗?

构建 Delphi 的正则表达式 class 的 PCRE 库是线程安全的。参见

但是,Delphi 包装器 TRegex 不是线程安全的。考虑在 TPerlRegEx.Match:

中对 pcre_exec 的调用
OffsetCount := pcre_exec(FPattern, FHints, @FSubject[0], FStop, 0, Opts, @Offsets[0],
  High(Offsets));

此处 FSubjectOffsetsTPerlRegEx 的成员,因此将在使用 TPerlRegEx 的此实例的不同线程之间共享,而该实例又由TRegEx.

的实例

为了 TRegEx 在您希望的意义上成为线程安全的(多个线程在共享编译的正则表达式上执行匹配),这些变量需要对匹配函数的每次调用都是私有的。