Qt:可重入和线程安全

2019-10-25  本文已影响0人  Alliawell

线程安全函数也是可重入函数,但可重入不一定是线程安全。

A thread-safe function is always reentrant, but a reentrant function is not always thread-safe.

线程安全函数:可以同步被多线程调用,即便访问了共享的数据,因为对共享数据的访问是序列化的。

可重入函数:仅在每个调用使用自己的数据时(如栈空间),才能被多线程调用。

(Qt对可重入函数的解释和其他地方的解释不同。)

作为扩展,一个类可重入,表示它的成员函数可以在多线程里调用,前提是每个线程使用一个不同的类对象。

一个类线程安全,表示多个线程可以同时调用其成员函数,即使这些线程使用的是同一个对象。

class Counter

  {

  public:

      Counter() { n = 0; }

      void increment() { ++n; }

      void decrement() { --n; }

      int value() const { return n; }

  private:

      int n;

  };

上面的类是可重入的,但不是线程安全的。

因为++和--操作不是原子的,实际上通常需要3个机器指令:

1. 将变量的值载入到寄存器中;

2.改变寄存器的值;

3.把寄存的值写回到变量中。

如果线程A和线程B同时载入了变量的值,然后增1,结果是值只被增加1次。

下面的类是线程安全的:

  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的类只有被明确标为线程安全(thread-safe),才可以在多线程里使用。

上一篇 下一篇

猜你喜欢

热点阅读