gpt4 book ai didi

c++ - Qt4 C++ : QString variable usage from multiple threads crashes

转载 作者:太空狗 更新时间:2023-10-29 23:17:03 25 4
gpt4 key购买 nike

我的 Qt4 代码使用一些 QThread 实例,这些实例在包含一些 QString 字段的公共(public)数据结构上运行。它可以归结为以下几点:

我的数据结构:

class My : public QObject{
Q_OBJECT
public:
QString foo;
};

线程实现:

class Thr : public QThread{
public:
My* my;
protected:
void run(){
while (true){
QString copy = my->foo;
QString bar = copy.toUpper();
my->foo = bar.toLower();
}
}
};

这是我为研究该问题而编写的测试应用程序。当然,它并没有做任何实际有用的事情:)

如果我初始化 My 的一个实例并用该实例启动一个线程,一切都很好。但是,当我使用相同的 My 实例启动第二个实例时,它会崩溃并显示不同的消息,看起来像是一些堆/堆栈/任何损坏。

这正常吗?我知道一般的多线程问题以及 Qt 的 QMutex,它可以避免这个问题。但就我正确理解 Qt 文档而言,我被允许以这种方式使用它。我不会同时对 QString 的同一个实例进行操作(可能是由于某些奇特的隐式共享机制——但文档指出这对用户来说是完全透明的?!)。

如前所述,我的问题不是关于如何重写代码,而是“从 Qt 4 开始,隐式共享类可以安全地跨线程复制,就像任何其他值类一样。它们是完全可重入的。隐式的分享真的是含蓄的。” ( http://qt-project.org/doc/qt-4.8/threads-modules.html ) 我理解错了。

最佳答案

如评论中所述,您可能试图从不同的线程写入相同的数据。我写“可能”只是因为你没有分享你的 QThread 子类的用法。

正如评论中所指出的,C++ 标准甚至不能保证赋值对于像内部有 QStringObject 子类这样的类是线程安全的。

您可以根据提示使用 std::atomic,尽管它仅在 C++11 之后才可用。一个更交叉的解决方案是为您的场景使用 QMutex,或者最好将 RAII 解决方案与 QMutexLocker 一起使用,它将自动为您处理解锁.所以你会像下面的代码。

class Thr : public QThread{
public:
My* my;
QMutex mutex; // <--- first addition
protected:
void run(){
while (true){
QString copy = my->foo;
QString bar = copy.toUpper();
QMutexLocker locker(&mutex); // <--- second addition
my->foo = bar.toLower();
}
}
};

当然,推荐的解决方案取决于更多因素,例如,您也可以根据手头的确切用例重新设计您的程序以不使用指针等。

关于c++ - Qt4 C++ : QString variable usage from multiple threads crashes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20735290/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com