c++ - 访问 Qt 小部件线程安全

标签 c++ multithreading qt

我使用 QPlainTextEdit 来显示一些文本。此文本将在 ui(主)线程之外的另一个线程中修改(追加),并向小部件发送信号

connect(this, SIGNAL(addText(QString)), mUi->plainTextEditLog, SLOT(appendPlainText(QString)));

...
emit addText(QString::fromStdString(someString));
...

另一个线程正在读取此 PlainTextEdit 的文本并将其写入文件

QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
    return;
}
file.write(mUi->plainTextEditLog->toPlainText().toUtf8());
file.close();

据我所知,Qt 小部件不是线程安全的。我想到了一个互斥体来锁定写入信号发射,但这不会真正锁定它,因为它只是异步发送信号。

我使用信号的原因是可以从多个线程调用写入方法,在这种情况下互斥量没有帮助,但信号非常完美。

第二个想法是将文本也存储在我的类中并使用互斥锁定字符串。但我不确定这是否非常有效,因为不仅有必须修改的 plaintextedit,还有作为拷贝的字符串。

最佳答案

本质上,只要在将信号从属于另一个线程的对象(参见 QObject::connect)连接到小部件(必须属于主线程)时使用自动或排队连接(参见 QObject::moveToThread) gui 线程),然后发出信号将是一个异步的“即发即弃”调用。您还可以通过指定它是阻塞排队连接来使调用同步,但我不推荐这样做,除非您确实需要它。

Qt 中的线程模型需要一点时间来理解,但您会逐渐喜欢上多线程代码中信号和槽的简单性,以及有多少代码不再需要使用互斥锁来保护它们的数据。

关于c++ - 访问 Qt 小部件线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30084371/

相关文章:

c++ - 调试线程时无限循环

python - 客户端没有响应 - Python 中的多线程

c++ - 在 DLL 中运行后,变量一直设置为 NULL

c++ - 如何有选择地为 VS2010 构建 Qt?

c++ - 隐式对象参数和 this 指针

c++ - std::ifstream::operator>> 无法将 0xABCD 转换为短字符?

java - 你如何在java中创建两个优先级队列数组?/Linux常量时间调度程序

python - 为什么QUndoStack.push()会执行QUndoCommand.redo()?

c++ - 扫描字符串字符的 ASCII 值

java - Java ME 中的奇怪错误