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 线程安全吗?
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)
这里FSubject
和Offsets
是 的成员TPerlRegEx
,因此将在使用 的实例的不同线程之间共享TPerlRegEx
,而该实例又由 的实例拥有TRegEx
。
为了TRegEx
在您希望的意义上实现线程安全(多个线程在共享编译的正则表达式上执行匹配),这些变量需要对于匹配函数的每次调用都是私有的。