C++ Q调节压力匹配螺纹安全

C++ Q调节压力匹配螺纹安全,c++,qt,thread-safety,C++,Qt,Thread Safety,我可以在多线程中安全地使用QtQRegularExpression而不锁定吗?regex对象将被声明为全局const,我将只使用const成员函数。单个显式共享的QRegularExpression实例不保证线程安全。如果您只调用const成员函数,那么您可能就可以了,但不能保证。唯一有文件证明的保证是,两个不同的实例可以在两个不同的线程中使用,而无需锁定,即实例之间隐式共享的任何数据都是内部同步的 然而,QRegularExpression是Qt的一种,这意味着复制QRegularExpres

我可以在多线程中安全地使用Qt
QRegularExpression
而不锁定吗?regex对象将被声明为全局
const
,我将只使用
const
成员函数。

单个显式共享的
QRegularExpression
实例不保证线程安全。如果您只调用
const
成员函数,那么您可能就可以了,但不能保证。唯一有文件证明的保证是,两个不同的实例可以在两个不同的线程中使用,而无需锁定,即实例之间隐式共享的任何数据都是内部同步的

然而,
QRegularExpression
是Qt的一种,这意味着复制
QRegularExpression
的实例非常便宜,因为副本将共享原始的数据,并且只有修改其中一个实例(写时复制)时才会复制实际数据。还有

因此,真正安全(高效)的方法是在每个线程中制作全局
QRegularExpression
的本地副本:

QRegularExpression globalRegex("[A-Za-z_][A-Za-z0-9_]*");

void thread1() {
    auto localRegex = globalRegex;
    // do something with localRegex
}

void thread2() {
    auto localRegex = globalRegex;
    // do something with localRegex
}

复制共享数据的唯一情况是修改一个本地regex对象,在这种情况下,单个全局regex对象无论如何都不是线程安全的。如果你真的想在线程之间共享一个全局
QRegularExpression
对象,那么最好使用锁。

我认为你不需要反复问同样的问题。Qt中没有任何东西是线程安全的,除非明确提到它是线程安全的。@KubaOber容器被称为只读线程安全的,为什么正则表达式不是?我只是想核实一下。当在不同线程中匹配编译的正则表达式时,PCRE似乎是线程安全的,QRegularExpression就是基于它的。只读线程安全是一种幻象,它太容易出错。我通过标记全局变量
thread\u local
解决了这个问题。这安全吗?@Nazar554它是安全的,但效率不高。当线程启动时,每个线程都会从头开始重新创建一个单独的正则表达式。请注意,这也意味着上面的示例是错误的——两个线程正在读取同一个实例而没有锁定。您应该首先复制,然后启动线程(给它副本)。@Oktalist:通常,它适用于所有隐式共享类:它们都是可重入的,而不是线程安全的。(总是参考文档来了解每个类的状态!)他们的constapi通常是线程安全的,我们正试图让它无处不在,并记录它(可能在qt6中)。但请注意不要过度依赖这一点;这里和那里都有通常的功能,会刺伤你的背部。对于QString,常见的gem是
utf16()
函数:根据我的经验,使用QRegularExpression的隐式共享副本比为每个线程创建独立实例的性能差得多。可能是因为访问共享数据时存在某种内部同步。