QT的可重入性与线程安全
来源:互联网 发布:面板数据到底是怎样的 编辑:程序博客网 时间:2024/06/02 02:15
可重入性与线程安全(Reentrancy and Thread-Safety)
原文: http://doc.qt.io/qt-5.6/threads-reentrancy.html
在本篇文章中,术语"可重入性"和"线程安全"被用来标记类与函数,以表明在多线程应用程序中它们可以被如何使用。
- 一个线程安全的函数可以同时被多个线程调用,甚至这些调用者会使用共享的数据也没有问题,因为对共享数据的访问是串行化的(serialized)。
- 一个可重入函数也可以同时被多个线程调用,但是每个调用者只能使用它自己的数据。
因此,一个线程安全的函数总是可重入的,但一个可重入的函数并不一定是线程安全的。
展开来说,一个可重入的类,指的是它的成员函数可以被多个线程安全地调用,只要每个线程使用这个类的不同的对象。而一个线程安全的类,指的是它的成员函数能够被多线程安全地调用,即使所有的线程都使用该类的同一个实例也没有关系。
注意:有一些Qt的类本来就是被有意地设计为多线程使用的,只有这样的类才在文档中被标明为线程安全的。如果一个函数没有被标记为线程安全的或可重入的,它就不应该被不同的线程使用。如果一个类没有被标记为线程安全的或可重入的,该类的实例就不应该被多个线程访问。
1. 将变量值装入寄存器
2. 增或减寄存器中的值
3. 将寄存器中的值装回主存
如果线程A和线程B同时将变量的旧值装入寄存器,增加它们的寄存器,再装回主存,它们最终会互相重写,而变量仅仅被增加了一次!
mutex数据成员被声明为mutable的,这是因为value()是一个const函数,但我们需要在其中lock和unlock这个mutex.
有些Qt的类和函数是线程安全的。它们主要是线程相关类(比如,QMutex)和一些基本函数(比如,QCoreApplication::postEvent())。
原文: http://doc.qt.io/qt-5.6/threads-reentrancy.html
在本篇文章中,术语"可重入性"和"线程安全"被用来标记类与函数,以表明在多线程应用程序中它们可以被如何使用。
- 一个线程安全的函数可以同时被多个线程调用,甚至这些调用者会使用共享的数据也没有问题,因为对共享数据的访问是串行化的(serialized)。
- 一个可重入函数也可以同时被多个线程调用,但是每个调用者只能使用它自己的数据。
因此,一个线程安全的函数总是可重入的,但一个可重入的函数并不一定是线程安全的。
展开来说,一个可重入的类,指的是它的成员函数可以被多个线程安全地调用,只要每个线程使用这个类的不同的对象。而一个线程安全的类,指的是它的成员函数能够被多线程安全地调用,即使所有的线程都使用该类的同一个实例也没有关系。
注意:有一些Qt的类本来就是被有意地设计为多线程使用的,只有这样的类才在文档中被标明为线程安全的。如果一个函数没有被标记为线程安全的或可重入的,它就不应该被不同的线程使用。如果一个类没有被标记为线程安全的或可重入的,该类的实例就不应该被多个线程访问。
可重入性
C++的类大多是可重入的,这只是因为它们只能访问它们自己的数据。任何线程都能访问一个可重入类的某实例的一个成员函数,只要此时没有其他线程能调用该实例的成员函数。比如,下面的Counter类就是可重入的:class Counter{public: Counter() { n = 0; } void increment() { ++n; } void decrement() { --n; } int value() const { return n; }private: int n;};这个类不是线程安全的,因为如果多线程试图修改成员n的话,结果就是不确定的。这是因为++和--操作都不总是原子性的。它们一般被展开为3条机器指令:
1. 将变量值装入寄存器
2. 增或减寄存器中的值
3. 将寄存器中的值装回主存
如果线程A和线程B同时将变量的旧值装入寄存器,增加它们的寄存器,再装回主存,它们最终会互相重写,而变量仅仅被增加了一次!
线程安全
很明显,访问应该是串行的: 线程A必须在无中断的情况下执行完3个步骤(原子性),然后线程B才能开始执行它的步骤,或者反过来。一个使得类是线程安全的简单方法就是用一个QMutex来保护对数据成员的所有访问。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类在其构造函数中自动锁定mutex,而在其析构函数中解锁。锁定mutex保证了其他线程的访问都将是串行化的。
mutex数据成员被声明为mutable的,这是因为value()是一个const函数,但我们需要在其中lock和unlock这个mutex.
关于Qt类的注意事项
许多Qt的类都是可重入的,但它们不是线程安全的,因为线程安全意味着要为锁定与解锁QMutex增加更多的开销。比如,QString是可重入的,但并不是线程安全的。你能够同时从多个线程访问不同的QString的实例,但你不能同时从多个线程访问QString的同一个实例(除非用QMutex保护访问)。有些Qt的类和函数是线程安全的。它们主要是线程相关类(比如,QMutex)和一些基本函数(比如,QCoreApplication::postEvent())。
注意: 多线程领域中的术语并不是完全标准化的。POSIX使用的可重入和线程安全的定义和它在C API里面的定义就是有些不同的。当Qt和其他面向对象的C++的类库一起使用时,要注意定义是明确无歧义的。
(完)
1 0
- QT的可重入性与线程安全
- QT可重入与线程安全
- QT可重入与线程安全
- Qt 多线程之可重入与线程安全
- Qt之可重入与线程安全
- Qt之可重入与线程安全
- 线程安全与可重入性
- 可重入性与线程安全
- Qt可重入的线程安全的概念
- 异步信号安全(可重入性)与线程安全
- 异步信号安全(可重入性)与线程安全
- 异步信号安全(可重入性)与线程安全
- 异步信号安全(可重入性)与线程安全
- 线程安全与线程不安全的区别
- Android的线程安全与UI线程
- 线程安全与线程不安全的区别
- 线程安全与线程不安全的区别
- 线程安全与线程不安全的理解
- 1005. 继续(3n+1)猜想 (25)
- java中创建线程主要有三种方式
- JAVA反射机制(二)
- 使用HashMap,如果key是自定义的类,就必须重写hashcode()和equals()。
- C++ map 转 string(自己实现的小代码)
- QT的可重入性与线程安全
- USACO5.15.2 新的一章w
- Spring-bean构造方法
- 使用jdbc+servlet进行登陆账号的认证
- Ukey,网页,web demo访问U盘用户验证
- BeanFactory or ApplicationContext in Spring
- android&&java 环境变量配置步骤
- USACO Section1.1 TEXT Submitting Solutions
- 全局变量与局部变量的小结