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

时间:2018-10-26 21:50:34

标签: regex multithreading delphi thread-safety pcre

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

思想:一方面,考虑一下,TRegEx实例将仅持有一个不变的(编译的)模式并直接处理参数输入,这是有道理的;或者将输入保持在(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线程安全吗?

1 个答案:

答案 0 :(得分:0)

构建Delphi的regex类的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));

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

要使it具有线程安全性,就意味着您想要(多个线程在共享的已编译正则表达式上执行匹配),这些变量将需要对match函数的每次调用专用。