可重入与线程安全(大多数Qt类是可重入,非线程安全的)

可重入与线程安全

在Qt文档中,术语“可重入”与“线程安全”被用来说明一个函数如何用于多线程程序。假如一个类的任何函数在此类的多个不同的实例上,可以被多个线程同时调用,那么这个类被称为是“可重入”的。假如不同的线程作用在同一个实例上仍可以正常工作,那么称之为“线程安全”的。 
大多数c++类天生就是可重入的,因为它们典型地仅仅引用成员数据。任何线程可以在类的一个实例上调用这样的成员函数,只要没有别的线程在同一个实例上调用这个成员函数。举例来讲,下面的Counter 类是可重入的:

class Counter
{
public:
      Counter() {n=0;}
      void increment() {++n;}
      void decrement() {--n;}
      int value() const {return n;}
private:
      int n;
};

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

1,把变量值装入寄存器 
2,增加或减少寄存器中的值 
3,把寄存器中的值写回内存

假如线程A与B同时装载变量的旧值,在寄存器中增值,回写。他们写操作重叠了,导致变量值仅增加了一次。很明显,访问应该串行化:A执行123步骤时不应被打断。使这个类成为线程安全的最简单方法是使用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使用了mutable关键字来修饰,因为我们在value()函数中对mutex进行加锁与解锁操作,而value()是一个const函数。 
大多数Qt类是可重入,非线程安全的。有一些类与函数是线程安全的,它们主要是线程相关的类,如QMutex,QCoreApplication::postEvent()。

http://blog.csdn.net/u013007900/article/details/50444508

时间: 2024-10-29 19:08:14

可重入与线程安全(大多数Qt类是可重入,非线程安全的)的相关文章

所谓线程安全和非线程安全

ArrayList和Vector有什么区别?HashMap和HashTable有什么区别?StringBuilder和StringBuffer有什么区别?这些都是Java面试中常见的基础问题.面对这样的问题,回答是:ArrayList是非线程安全的,Vector是线程安全的:HashMap是非线程安全的,HashTable是线程安全的:StringBuilder是非线程安全的,StringBuffer是线程安全的.这些是面试时经常问道的问题,但是有些情况下面试的人会追问:什么是线程安全,什么是非

Windows下的PHP安装文件线程安全和非线程安全的区别

从2000年10月20日发布的第一个Windows版的PHP3.0.17开始的都是线程安全的版本,这是由于与Linux/Unix系统是采用 多进程的工作方式不同的是Windows系统是采用多线程的工作方式.如果在IIS下以CGI方式运行PHP会非常慢,这是由于CGI模式是建立在多进程 的基础之上的,而非多线程.一般我们会把PHP配置成以ISAPI的方式来运行,ISAPI是多线程的方式,这样就快多了.但存在一个问题,很多常用的 PHP扩展是以Linux/Unix的多进程思想来开发的,这些扩展在IS

SimpleDateFormat非线程安全

以前没有注意过的问题呀! 留着 自己好好看看. 出自 :http://www.cnblogs.com/zemliu/p/3290585.html 1. 原因 SimpleDateFormat(下面简称sdf)类内部有一个Calendar对象引用,它用来储存和这个sdf相关的日期信息,例如sdf.parse(dateStr), sdf.format(date) 诸如此类的方法参数传入的日期相关String, Date等等, 都是交友Calendar引用来储存的.这样就会导致一个问题,如果你的sdf

Qt 类外调用一个 private slots 函数

MainWindow中 private slots 函数 void print_on_log(QString strtemp);输出一个字符串到编辑窗口中 class MainWindow:publicQMainWindow {Q_OBJECTpublic:explicitMainWindow(QWidget*parent=0);~MainWindow();privateslots:voidprint_on_log(QStringstrtemp); 定义一个新类Test_one在此类中调用上面的

线程同步-iOS多线程编程指南(四)-08-多线程

首页 编程指南 Grand Central Dispatch 基本概念 多核心的性能 Dispatch Sources 完结 外传:dispatch_once(上) Block非官方编程指南 基础 内存管理 揭开神秘面纱(上) 揭开神秘面纱(下) iOS多线程编程指南 关于多线程编程 线程管理 Run Loop 线程同步 附录 Core Animation编程指南 Core Animation简介 基本概念 渲染架构 几何变换 查看目录 中文手册/API ASIHTTPRequest Openg

线程池与非线程池应用场景及模型对比分析

在网络编程中经常用到线程池和连接池,今天就对其中常用的线程池的基本应用场景和模型做个简单的对比分析. 1.  业务流程对比 a.  非线程池业务流模型: 上图标识了基本的非线程池的线程模型,前端1有多少连接则前端客户端2与前端服务器端3均需建立一对一的线程数进行响应的连接.前端服务器端3与后端服务器端4也需建立响应数目的线程进行连接处理相关业务. 当一个任务处理完毕后线程退出,在下一个任务到来的时候前端服务器端创建新的线程来处理新的任务. b.线程池模型: 上图标识了基本的线程池模型.前端客户端

Qt类中使用定时器

QT定时器只能使用在进程或线程中. QT类中如果需要定时器,可以把定时工作安排在一个线程中执行. class aaa : public QThread { Q_OBJECT ... protected: //重写run函数 void run(); public slots: void timerOut(); private: QTimer *timer; } aaa::aaa(QThread *parent):QThread(parent) { timer = new QTimer(0); co

C#多线程开发8:线程同步之Mutex类

以下代码模拟"从自动取款机中取钱"的操作:当账户余额大于等于1000时,取出1000放入口袋.代码中使用两个线程同时执行取钱操作,若不进行同步处理,可能会存在两个线程同时进入取钱逻辑,导致最终取出2000的错误结果.所以代码中使用Mutex类同步线程访问取钱逻辑(临界资源). using System; using System.Threading; namespace MutexExample { class Program { private static Mutex mutex

Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分

Windows版的PHP从版本5.2.1开始有Thread Safe(线程安全)和None Thread Safe(NTS,非线程安全)之分,这两者不同在于何处?到底应该用哪种?这里做一个简单的介绍. 从2000年10月20日发布的第一个Windows版的PHP3.0.17开始的都是线程安全的版本,这是由于与Linux/Unix系统是采用多进程的工作方式不同的是Windows系统是采用多线程的工作方式.如果在IIS下以CGI方式运行PHP会非常慢,这是由于CGI模式是建立在多进程的基础之上的,而