可重入函数(Reentrancy)和线程安全函数(Thread-Safety)

线程安全函数:
它可以被多线程同时调用,即使使用共享数据,也可以。因为共享的数据在调用时已经做了序列化处理。

可重入函数:
一个可重入函数可以被多线程同时调用,前提时并发调用时必须是使用自己的数据。

因此,线程安全函数始终是可重入的,但可重入函数并非始终是线程安全的。

如果可以从多个线程安全地调用其成员函数,则该类称为可重入的,只要每个线程使用该类的不同实例即可。 如果可以从多个线程安全地调用其成员函数,则该类是线程安全的,即使所有线程都使用该类的相同实例也是如此。

可重入(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一起使用时,请确保已理解这些定义

posted @ 2020-08-04 13:57  瓜蛋  阅读(622)  评论(0编辑  收藏  举报