解析 QT 多线程程序之可重入与线程安全 中篇

移动开发
在一个程序中,这些独立运行的程序片断叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理”。多线程处理一个常见的例子就是用户界面。

QT 多线程程序之可重入与线程安全 是本节要介绍的内容,继续着 解析 QT 多线程程序详细设计 上篇 ,开始介绍。先来看内容。

Qt文档中,术语“可重入”与“线程安全”被用来说明一个函数如何用于多线程程序。假如一个类的任何函数在此类的多个不同的实例上,可以被多个线程同时调用,那么这个类被称为是“可重入”的。假如不同的线程作用在同一个实例上仍可以正常工作,那么称之为“线程安全”的。

大多数c++类天生就是可重入的,因为它们典型地仅仅引用成员数据。任何线程可以在类的一个实例上调用这样的成员函数,只要没有别的线程在同一个实例上调用这个成员函数。举例来讲,下面的Counter 类是可重入的:

  1. class Counter{public:      Counter() {  
  2. n=0;  
  3. }   
  4.      void increment() {  
  5. ++n;  
  6. }  
  7.       void decrement() {  
  8. --n;  
  9. }  
  10.       int value() const {  
  11. return n;  
  12. }private:      int n;  
  13. }; 

这个类不是线程安全的,因为假如多个线程都试图修改数据成员 n,结果未定义。这是因为c++中的++和--操作符不是原子操作。实际上,它们会被扩展为三个机器指令:

1,把变量值装入寄存器

2,增加或减少寄存器中的值

3,把寄存器中的值写回内存

假如线程A与B同时装载变量的旧值,在寄存器中增值,回写。他们写操作重叠了,导致变量值仅增加了一次。很明显,访问应该串行化:A执行123步骤时不应被打断。使这个类成为线程安全的最简单方法是使用QMutex来保护数据成员:

  1. class Counter{public:     Counter() {  
  2.  n = 0;  
  3.  }  
  4.      void increment() {  
  5.  QMutexLocker locker(&mutex); ++n;  
  6.  }   
  7.     void decrement() {  
  8.  QMutexLocker locker(&mutex);  
  9.  --n;  
  10.  }   
  11.     int value() const {  
  12.  QMutexLocker locker(&mutex);  
  13.  return n;  
  14.  }private:     mutable QMutex mutex;  
  15.      int n;  
  16. }; 

QMutexLocker类在构造函数中自动对mutex进行加锁,在析构函数中进行解锁。随便一提的是,mutex使用了mutable关键字来修饰,因为我们在value()函数中对mutex进行加锁与解锁操作,而value()是一个const函数。

大多数Qt类是可重入,非线程安全的。有一些类与函数是线程安全的,它们主要是线程相关的类,如QMutex,QCoreApplication::postEvent()。

线程与QObjects

QThread 继承自QObject,它发射信号以指示线程执行开始与结束,而且也提供了许多slots。更有趣的是,QObjects可以用于多线程,这是因为每个线程被允许有它自己的事件循环。

小结:QT 多线程程序之可重入与线程安全的内容介绍完了,希望本文能够对你有所帮助,如果你对本文感兴趣或者需要获得更多的资料,请参考

解析QT多线程程序详细设计之QObject可重入性 下篇 。

责任编辑:zhaolei 来源: 互联网
相关推荐

2011-06-22 16:02:37

Qt 多线程 重入

2011-06-22 14:47:51

QT 多线程 QObject

2017-03-08 16:25:54

Linux多线程函数

2011-06-22 14:30:44

QT 多线程 线程

2011-06-24 11:03:31

Qt 多线程 线程

2011-06-24 11:12:39

Qt 多线程 线程

2022-05-26 08:31:41

线程Java线程与进程

2009-03-12 10:52:43

Java线程多线程

2011-06-22 16:18:23

QT 多线程 QSocket

2009-07-03 16:53:11

Servlet容器

2011-06-02 17:27:49

iphone 多线程

2011-04-18 09:22:38

多线程

2011-06-22 16:08:40

Qt 多线程 事件循环

2023-06-07 13:49:00

多线程编程C#

2011-06-13 10:03:19

Qt 多线程 编程

2011-06-22 15:50:45

QT 线程

2024-02-27 10:44:58

C#线程后端

2012-06-20 14:07:28

多线程架构单线程

2011-06-16 10:38:13

Qt多线程编程

2011-06-13 10:41:17

JAVA
点赞
收藏

51CTO技术栈公众号