QObject 重入和线程安全

Posted

技术标签:

【中文标题】QObject 重入和线程安全【英文标题】:QObject reentrancy and thread safety 【发布时间】:2013-12-18 12:15:11 【问题描述】:

在this的文章中说: 一些 QObject 是可重入的,因此可以同时从多个线程中使用这些类

我想一段可重入的代码也应该是线程安全的。

但是,同一篇文章继续说:

请注意,这些类被设计为在单个线程中创建和使用;在一个线程中创建对象并从另一个线程调用其函数并不能保证有效。

这不是矛盾吗?最后是什么意思?我可以安全地跨线程调用 QObject 函数吗?

我已复制以下文章的相关部分:

QObject 重入

QObject 是可重入的。它的大部分非 GUI 子类,例如 QTimer、QTcpSocket、QUdpSocket、QFtp 和 QProcess,也是可重入的,使得使用这些类成为可能 同时来自多个线程。请注意,这些类是 设计为在单个线程中创建和使用;创造 一个线程中的对象并从另一个线程调用其函数 不保证能正常工作。

【问题讨论】:

a thread-safe function is always reentrant, but a reentrant function is not always thread-safe. 但是,据说有些QObjects是可重入的,使得多个线程同时使用这些类成为可能 使用。不使用对象 @BeniBela:好吧,我不太明白其中的区别。 正是贝尼贝拉所说的。 class is said to be reentrant if its member functions can be called safely from multiple threads, as long as each thread uses a different instance of the class. 【参考方案1】:

我认为下面documentation 的以下引用应该可以帮助您理解它们之间的区别。简而言之,请注意您引用的第一个引用是关于类本身的,第二个引用是关于类实例的对象。

重入和线程安全

在整个文档中,术语可重入和线程安全用于标记类和函数,以指示它们如何在多线程应用程序中使用:

可以从多个线程同时调用线程安全函数,即使调用使用共享数据也是如此,因为对共享数据的所有引用都是序列化的。

也可以从多个线程同时调用可重入函数,但前提是每次调用都使用自己的数据。

通过扩展,如果一个类的成员函数可以从多个线程安全地调用,只要每个线程使用该类的不同实例,就可以说它是可重入的。如果可以从多个线程安全地调用该类的成员函数,则该类是线程安全的,即使所有线程都使用该类的同一个实例。

注意:仅当 Qt 类打算由多个线程使用时,它们才被记录为线程安全的。如果函数未标记为线程安全或可重入,则不应从不同的线程中使用它。如果一个类未标记为线程安全或可重入,则不应从不同线程访问该类的特定实例。

【讨论】:

以上是关于QObject 重入和线程安全的主要内容,如果未能解决你的问题,请参考以下文章

可重入和线程安全

Qt入门教程QObject篇重入性和线程安全

Qt入门教程QObject篇重入性和线程安全

线程安全与可重入

可重入函数线程安全volatile

从另一个线程发出信号是否安全?