前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >翻译 | 可重入与线程安全

翻译 | 可重入与线程安全

作者头像
Qt君
发布2020-03-19 16:13:17
1.1K0
发布2020-03-19 16:13:17
举报
文章被收录于专栏:跟Qt君学编程

❝Qt君今天在Qt帮助文档中看到一篇不错的文章,翻译分享给大家。❞

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

  • 「即使在调用使用共享数据时,也可以从多个线程同时调用线程安全的函数,因为对共享数据的所有引用都是序列化的」
  • 「也可以从多个线程同时调用可重入函数,但前提是每次调用都使用自己的数据」

「因此,线程安全的函数总是可重入的,但可重入的函数并不总是线程安全的」

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

「注意」:Qt类只有在被多个线程使用时才会被记录为线程安全的。如果函数未标记为线程安全或可重入,则不应从不同的线程使用它。如果一个类没有标记为线程安全或可重入,则不应该从不同的线程来访问该类的特定实例。

可重入

  C++类通常是可重入的,因为它们只访问自己的成员数据。任何线程都可以在可重入类的实例上调用成员函数,只要没有其他线程可以同时在该类的同一实例上调用成员函数。例如,下面的Counter类是可重入的:

代码语言:javascript
复制
class Counter
{
public:
    Counter() { n = 0; }

    void increment() { ++n; }
    void decrement() { --n; }
    int value() const { return n; }

private:
    int n;
};

  但是,这个类不是线程安全的,因为如果多个线程试图修改数据成员n,结果是未定义的。这是因为++n--n运算符并不总是原子性的。实际上,它们通常会扩展到这三个机器指令:

  1. 在寄存器中加载变量的值。
  2. 寄存器值的递增或递减。
  3. 将寄存器的值存储回主内存中。

  如果线程A和线程B同时加载变量的旧值,增加它们的寄存器,并将其存储回去,它们最终会相互覆盖,造成的后果是变量n只增加一次!

线程安全

  显然,访问必须是序列化的:线程A必须执行上述步骤123中的原子性不中断,然后线程B才能执行相同的步骤,反之亦然。要想某个类线程安全的简单方法是用一个QMutex来保护所有对数据成员的访问:

代码语言:javascript
复制
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;
};

  QMutexLocker类在其构造函数中自动锁定互斥锁,并在调用析构函数时在函数结束时解锁它。锁定互斥锁可以确保来自不同线程的访问将被序列化。互斥锁数据成员使用可变限定符声明的,因为我们需要在value()中锁定和解锁互斥锁,同时它还是一个const修饰的函数。

关于Qt类的注释

「许多Qt类是可重入的,但它们不是线程安全的,因为使它们成为线程安全会导致重复锁定和解锁一个QMutex的额外开销」。例如,QString是可重入的,但不是线程安全的。您可以同时从多个线程安全地访问不同的QString实例,但是不能同时从多个线程安全地访问相同的QString实例(除非您使用QMutex保护自己的访问)。

  一些Qt类和函数是线程安全的。这些类主要是与线程相关的类(如QMutex)和基本函数(如QCoreApplication::postEvent())。

「注意」:多线程领域的术语并不是完全标准化的。POSIX使用可重入和线程安全的定义,这与它的C语言API有些不同。在Qt中使用其他面向对象的C++类库时,请确保理解这些定义。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Qt君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 可重入
  • 线程安全
  • 关于Qt类的注释
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档