System.RegularExpressions.TRegEx 线程安全吗?

Max*_*Max 5 regex delphi multithreading pcre thread-safety

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

想法:一方面,考虑一下,一个TRegEx实例只包含一个不可变(编译)模式并直接处理参数输入是有道理的,或者将此输入保留在 ( TMatch) 返回值中以供以后可能的继续- - 例如 with NextMatch,它是在 上TMatch而不是在 上实现的TRegEx。并且底层的开源 PCRE 库似乎是线程安全的。所有这些都符合上面的场景。另一方面,我认为一个TRegEx实例通常不是线程安全的,因为例如,在function TRegEx.Match(const Input: String): TMatch(如上所用)中,看起来要与模式匹配的字符串在匹配之前首先存储到实例中。和相同的嵌套TPerlRegEx实例在各种功能链中传递并保持活动状态。TRegEx例如,共享实例似乎需要防止不协调的访问,例如使用临界区。

也就是说,我怀疑TRegEx不是线程安全的,但我想请教多线程和裁定线程安全的人进行确认。因此,我的问题 - 非常笼统,独立于它演变而来的应用程序:

问题:TRegEx 线程安全吗?

Dav*_*nan 1

Delphi 的正则表达式类构建于其上的 PCRE 库是线程安全的。看到PCRE pcre_exec 线程安全了吗?

然而,Delphi 包装器TRegex不是线程安全的。pcre_exec考虑对in进行的调用TPerlRegEx.Match

OffsetCount := pcre_exec(FPattern, FHints, @FSubject[0], FStop, 0, Opts, @Offsets[0],
  High(Offsets));
Run Code Online (Sandbox Code Playgroud)

这里FSubjectOffsets是 的成员TPerlRegEx,因此将在使用 的实例的不同线程之间共享TPerlRegEx,而该实例又由 的实例拥有TRegEx

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