背景:我遇到的一个应用程序使用 TRegEx
来自多个线程的单例。单例初始化为 TRegEx.Create(Pattern, [roCompiled])
在类构造函数中,线程使用它以 RegEx.Match(Value).Groups
开头,并且似乎没有采用同步机制,但是,应用程序运行良好。不过,这只是 TThread.Execute
的一小部分覆盖并且线程上的负载很小。所以这可能总是偶然的,因为线程不太可能在关键部分相互交叉。
想法:一方面,考虑一下,TRegEx
是有道理的。 instance 只会持有一个不可变(编译)模式并直接处理参数输入,或者将此输入保留在(TMatch
)返回值中以供以后可能的延续 - 就像 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 的正则表达式类的 PCRE 库是线程安全的。见 PCRE pcre_exec thread safe?
但是,Delphi 包装器 TRegex
不是线程安全的。考虑对 pcre_exec
的调用。在 TPerlRegEx.Match
:
OffsetCount := pcre_exec(FPattern, FHints, @FSubject[0], FStop, 0, Opts, @Offsets[0],
High(Offsets));
这里FSubject
和 Offsets
是 TPerlRegEx
的成员因此将使用 TPerlRegEx
的这个实例在不同线程之间共享,而它又归 TRegEx
的实例所有.对于
TRegEx
在您希望的意义上是线程安全的(多个线程在共享的编译正则表达式上执行匹配)这些变量需要对匹配函数的每次调用都是私有(private)的。
关于regex - System.RegularExpressions.TRegEx 是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53016707/