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