偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Qt 多線程之可重入與線程安全 上篇

移動(dòng)開發(fā)
大多數(shù)c++類天生就是可重入的,因?yàn)樗鼈兊湫偷貎H僅引用成員數(shù)據(jù)。任何線程可以在類的一個(gè)實(shí)例上調(diào)用這樣的成員函數(shù),只要沒有別的線程在同一個(gè)實(shí)例上調(diào)用這個(gè)成員函數(shù)。

Qt 多線程之可重入線程安全是本節(jié)要介紹的內(nèi)容。在Qt文檔中,術(shù)語“可重入”與“線程安全”被用來說明一個(gè)函數(shù)如何用于多線程程序。假如一個(gè)類的任何函數(shù)在此類的多個(gè)不同的實(shí)例上,可以被多個(gè)線程同時(shí)調(diào)用,那么這個(gè)類被稱為是“可重入”的。假如不同的線程作用在同一個(gè)實(shí)例上仍可以正常工作,那么稱之為“線程安全”的。

大多數(shù)c++類天生就是可重入的,因?yàn)樗鼈兊湫偷貎H僅引用成員數(shù)據(jù)。任何線程可以在類的一個(gè)實(shí)例上調(diào)用這樣的成員函數(shù),只要沒有別的線程在同一個(gè)實(shí)例上調(diào)用這個(gè)成員函數(shù)。舉例來講,下面的Counter 類是可重入的:

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

這個(gè)類不是線程安全的,因?yàn)榧偃缍鄠€(gè)線程都試圖修改數(shù)據(jù)成員 n,結(jié)果未定義。這是因?yàn)閏++中的++和--操作符不是原子操作。實(shí)際上,它們會(huì)被擴(kuò)展為三個(gè)機(jī)器指令:

1,把變量值裝入寄存器

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

3,把寄存器中的值寫回內(nèi)存

假如線程A與B同時(shí)裝載變量的舊值,在寄存器中增值,回寫。他們寫操作重疊了,導(dǎo)致變量值僅增加了一次。很明顯,訪問應(yīng)該串行化:A執(zhí)行123步驟時(shí)不應(yīng)被打斷。使這個(gè)類成為線程安全的最簡單方法是使用QMutex來保護(hù)數(shù)據(jù)成員:

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類在構(gòu)造函數(shù)中自動(dòng)對(duì)mutex進(jìn)行加鎖,在析構(gòu)函數(shù)中進(jìn)行解鎖。隨便一提的是,mutex使用了mutable關(guān)鍵字來修飾,因?yàn)槲覀冊(cè)趘alue()函數(shù)中對(duì)mutex進(jìn)行加鎖與解鎖操作,而value()是一個(gè)const函數(shù)。

大多數(shù)Qt類是可重入,非線程安全的。有一些類與函數(shù)是線程安全的,它們主要是線程相關(guān)的類,如QMutex,QCoreApplication::postEvent()。

線程與QObjects

QThread 繼承自QObject,它發(fā)射信號(hào)以指示線程執(zhí)行開始與結(jié)束,而且也提供了許多slots。更有趣的是,QObjects可以用于多線程,這是因?yàn)槊總€(gè)線程被允許有它自己的事件循環(huán)。
QObject 可重入

QObject是可重入的。它的大多數(shù)非GUI子類,像QTimer,QTcpSocket,QUdpSocket,QHttp,QFtp,QProcess也是可重入的,在多個(gè)線程中同時(shí)使用這些類是可能的。需要注意的是,這些類被設(shè)計(jì)成在一個(gè)單線程中創(chuàng)建與使用,因此,在一個(gè)線程中創(chuàng)建一個(gè)對(duì)象,而在另外的線程中調(diào)用它的函數(shù),這樣的行為不能保證工作良好。有三種約束需要注意:

1,QObject的孩子總是應(yīng)該在它父親被創(chuàng)建的那個(gè)線程中創(chuàng)建。這意味著,你絕不應(yīng)該傳遞QThread對(duì)象作為另一個(gè)對(duì)象的父親(因?yàn)镼Thread對(duì)象本身會(huì)在另一個(gè)線程中被創(chuàng)建)

2,事件驅(qū)動(dòng)對(duì)象僅僅在單線程中使用。明確地說,這個(gè)規(guī)則適用于"定時(shí)器機(jī)制“與”網(wǎng)格模塊“,舉例來講,你不應(yīng)該在一個(gè)線程中開始一個(gè)定時(shí)器或是連接一個(gè)套接字,當(dāng)這個(gè)線程不是這些對(duì)象所在的線程。

3,你必須保證在線程中創(chuàng)建的所有對(duì)象在你刪除QThread前被刪除。這很容易做到:你可以run()函數(shù)運(yùn)行的棧上創(chuàng)建對(duì)象。

盡管QObject是可重入的,但GUI類,特別是QWidget與它的所有子類都是不可重入的。它們僅用于主線程。正如前面提到過的,QCoreApplication::exec()也必須從那個(gè)線程中被調(diào)用。實(shí)踐上,不會(huì)在別的線程中使用GUI類,它們工作在主線程上,把一些耗時(shí)的操作放入獨(dú)立的工作線程中,當(dāng)工作線程運(yùn)行完成,把結(jié)果在主線程所擁有的屏幕上顯示。

小結(jié):Qt 多線程之可重入與線程安全關(guān)于本節(jié)的內(nèi)容介紹完了,請(qǐng)接著看 Qt 多線程之逐線程事件循環(huán) 下篇。更多資料請(qǐng)參考編輯推薦。

責(zé)任編輯:zhaolei 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-06-22 14:38:09

QT 多線程 線程安全

2017-03-08 16:25:54

Linux多線程函數(shù)

2011-06-22 16:08:40

Qt 多線程 事件循環(huán)

2011-06-22 14:30:44

QT 多線程 線程

2011-06-22 14:47:51

QT 多線程 QObject

2011-06-24 11:03:31

Qt 多線程 線程

2021-12-26 18:22:30

Java線程多線程

2010-03-16 17:16:38

Java多線程

2010-01-21 11:25:44

linux多線程線程資源

2011-06-22 10:12:08

Qt 線程

2021-12-14 08:28:08

Java多線程線程

2021-02-25 15:58:46

C++線程編程開發(fā)技術(shù)

2021-12-28 09:10:55

Java線程狀態(tài)

2021-03-05 07:38:52

C++線程編程開發(fā)技術(shù)

2017-05-31 14:03:07

Java多線程內(nèi)置鎖與顯示鎖

2011-06-13 10:03:19

Qt 多線程 編程

2017-05-08 11:46:15

Java多線程

2012-04-16 10:12:54

Java線程

2013-06-07 16:30:08

iOS多線程iOS開發(fā)NSThread

2011-06-30 17:31:32

Qt 多線程 信號(hào)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)