背景:我遇到的一个应用程序在多个线程中使用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线程安全吗?
答案 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));
这里FSubject
和Offsets
是TPerlRegEx
的成员,因此将使用TPerlRegEx
的此实例在不同的线程之间共享,而该实例又由TRegEx
的实例拥有TRegEx
。
要使it
具有线程安全性,就意味着您想要(多个线程在共享的已编译正则表达式上执行匹配),这些变量将需要对match函数的每次调用专用。