一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

1.什么是类的线程安全(或线程安全的类)?
  了解多线程的人太概都知道,类地线是玄全比可重入更加严格、它要求在不回线程同过调用类回一实侧的成局画数、而不会发程序的递溃。
2.哪些情况下不用考虑线程安全问题?
2.1在多线程中对bool,int,float,QString等类型的操作,你不用考虑任何安全性问题。
  因为你无论以什么方式在不同线程中对这些类型进行操作,都像真正的原子性操作一样(其实不是严格的原子性操作),完全不会引起程序崩溃。我想这可能是QT已经对这些类型进行了线程安全保障。
比如,我下面的这个类本身就是线程安全的:

 1 class Counter:public QObject 
 2 {
 3   Q_OBJECT 
 4 public: 
 5     Counter(){n=0;}
 6     void O1(){++n:}
 7     void O2(){-n;}
 8     int get()const{return n:}
 9 private: 
10     int n;
11 };

2.2在多线程中使用信号槽机制进行资源共享时,不用考虑线程安全问题。
  例如在两个不同的子线程中通过信号槽将字符串信息传递到Ul线程,用于更新界面的显示,这个操作是线程安全的,因为信号槽作为QT独创的通信机制,是线程安全的。
3.设计一个线程安全的类
3.1先展示一个未进行线程安全保障的类是如何引发崩溃的
定义一个非线程安全的类:

 1 class Thread1: public QThread 
 2 {
 3 public: 
 4     Thread1(); 
 5     virtual void run() override; 
 6 }
 7 class Thread2: public QThread 
 8 {
 9 public:
10     Thread2(); 
11     virtual void run() override;
12 }

在两个子线程中对这个类的同一实例进行访问:

不出意外,程序运行一分钟以内就会崩溃。
3.2安全写法1使用互斥量QMutex.并使用lock)和unlock0方法进行锁定和解锁,但这个方法难以对返回参数进行保护

 3.2安全写法2使用互斥量QMutex,并使用QMutexLocker 进行锁定,当QMutexLocker从栈释放后,自动解锁

 3.3安全写法3使用读写锁 QReadWriteLock,并使用 lockForRead0和lockForWrite)对读或写进行保护,这种方法相比QMutex效率更高,因为它允许多线程同时读。

3.4更多保证类的线程安全性的办法
  1.使用生产者一消费者模式,通过缓冲区产生多个数据的备份,可提高线程间数据共享的效率
  2.使用socket进行线程间,甚至进程间的数据共享3.类不提供访问实例中成员的方法,而是通过信号槽机制,进行线程间的数据共享

posted on 2022-07-21 09:10  一杯清酒邀明月  阅读(1058)  评论(0编辑  收藏  举报