线程安全函数:
它可以被多线程同时调用,即使使用共享数据,也可以。因为共享的数据在调用时已经做了序列化处理。
可重入函数:
一个可重入函数可以被多线程同时调用,前提时并发调用时必须是使用自己的数据。
因此,线程安全函数始终是可重入的,但可重入函数并非始终是线程安全的。
如果可以从多个线程安全地调用其成员函数,则该类称为可重入的,只要每个线程使用该类的不同实例即可。 如果可以从多个线程安全地调用其成员函数,则该类是线程安全的,即使所有线程都使用该类的相同实例也是如此。
可重入(Reentrancy)
c++类大多都是可重入的,这是因为他们访问他们自己的成员变量。任何线程调都可以调用一个实例的成员函数,没有其它线程同时调用同一个实例的成员函数。
例如以下的类是一个可重入的类
class Counter { public: Counter() { n = 0; } void increment() { ++n; } void decrement() { --n; } int value() const { return n; } private: int n; };
这个类不是线程安全的,因为多个线程可以试图修改同一个实例变量n,最后会得到一个意料之外的结果。因为++和--操作符不是原子操作。
线程安全(Thread-Safe)
class Counter { public: Counter() { n = 0; } void increment() { QMutexLocker locker(&mutex); ++n; } void decrement() { QMutexLocker locker(&mutex); --n; } int value() const { QMutexLocker locker(&mutex); return n; } private: mutable QMutex mutex; int n; };
使用Qt时要注意:
许多Qt的类是可重入的类,而不是线程安全的。例如,QString是一个可重入的类而不是一个线程安全的类,你可以多线程安全的访问不同的QString但是不能一个线程同时访问同一个QString,如果非要这样做,一定要用Mutex来保护。
一些QT的类和函数是线程安全的, 他们主要是一些线程相关的类(比如QMutex)或者是一些基础函数例如(QCoreApplication:postEvent)
注意:多线程领域的术语尚未标准化,POSIX使用reentrant和thread-safe,有些时候与C API不同。当将其他面向对象的C ++类库与Qt一起使用时,请确保已理解这些定义