成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

QT核心編程之Qt線程 (3)

移動開發
Qt對線程提供了支持,它引入了一些基本與平臺無關的線程類、線程安全傳遞事件的方式和全局Qt庫互斥量允許你從不同的線程調用Qt的方法。

QT核心編程之Qt線程是本節要介紹的內容,QT核心編程我們要分幾個部分來介紹,想參考更多內容,請看末尾的編輯推薦進行詳細閱讀,先來看本篇內容。

Qt線程提供了支持,它引入了一些基本與平臺無關的線程類、線程安全傳遞事件的方式和全局Qt庫互斥量允許你從不同的線程調用Qt的方法。Qt中與線程應用相關的類如表6所示。

QT核心編程之Qt線程 

表6 Qt中與線程相關的類

使用線程需要Qt提供相應的線程庫的支持,因此,在編譯安裝Qt時,需要加上線程支持選項。

當在Windows操作系統上編譯Qt時,線程支持是在一些編譯器上的一個選項。在Windows操作系統上編譯應用程序時,通過在qconfig.h文件中增加一個選項來解決來解決這個問題。

在Mac OS X和Unix上編譯Qt時,你應在運行configure腳本時添加-thread選項。在Unix平臺上,多線程程序必須用特殊的線程支持庫連接,多線程程序必須連接線程支持庫libqt-mt,而不是標準的Qt庫。編譯應用程序時,你應該使用宏定義QT_THREAD_SUPPORT來編譯(如:編譯時使用-DQT_THREAD_SUPPORT)。

1、線程類QThread

在 Qt中提供了QThread線程類,它提供了創建一個新線程的方法。線程通過重載 QThread::run()函數開始執行的,這一點與Java中的線程類相似。

示例1:一個簡單的線程

下面的例子實現了一個簡單的繼承自QThread的用戶線程類,并運行2個線程,線程b在線程a運行完后運行。代碼列出如下:

  1. class MyThread : public QThread {  
  2. public:    virtual void run();  
  3. };  
  4.  void MyThread::run()   //運行線程{  
  5.     for( int count = 0;  
  6.  count < 20; count++ ) {  
  7.         sleep( 1 );  
  8.         qDebug( "Ping!" );  
  9.     }  
  10. }   
  11. int main(){   
  12.    MyThread a;  
  13.     MyThread b;  
  14.     a.start(); //通過調用run()函數來執行  
  15.     b.start();  
  16.     a.wait();  
  17.     b.wait();  

只有一個線程類是不夠的,對于支持多線程的程序來說,還需要保護兩個不同的線程對數據的同時訪問,因此 Qt 提供了QMutex 類,一個線程可以鎖住互斥量,當互斥量被鎖住時,將阻塞其它線程訪問臨界數據,直到這個線程釋放互斥量。這樣,可以保護臨界數據一次只能被一個線程訪問。

Qt庫互斥量(qApp->lock()和qApp->unlock())是在訪問Qt的GUI界面資源時用到的互斥量。在 Qt中沒有使用互斥量而調用一個函數通常會導致不可預知的行為。從另外一個線程中調用Qt的一個GUI相關函數需要使用Qt庫互斥量。在這種情況下,所有訪問圖形或窗口系統資源的函數都與GUI相關。如果對象僅被一個線程訪問,使用容器類,字符串或者輸入/輸出類不需要任何互斥量。

2、線程安全的事件傳遞

在Qt中,一個線程總是一個事件線程,線程從窗口系統中拉出事件并且把它們分發給窗口部件。靜態方法QThread::postEvent從線程中郵遞事件,而不是從事件線程。事件線程被喚醒并且事件象一個正常窗口系統的事件一樣在事件線程中被分發。例如,你可以從不同的線程強制一個窗口部件進行重繪,方法如下:

  1. QWidget *mywidget;QThread::postEvent( mywidget, new QPaintEvent( QRect(0, 0, 100, 100) ) ); 

上述代碼將異步地使mywidget在它區域中重繪一塊100*100的正方形區域。

另外,還需要一些機制使得處于等待狀態的線程在給定條件下被喚醒。QWaitCondition 類就提供了這種功能。線程等待的條件QWaitCondition滿足,QWaitCondition表明發生了什么事情,它阻塞直到這件事情發生。當發生給定的事情時,QWaitCondition 將喚醒等待該事情的所有線程或者喚醒任意一個被選中的線程。(這和POSIX線程條件變量具有相同功能,是Unix上的一種實現。)

示例2:QWaitCondition類應用

下面這個例子的功能是:當你按下按鈕,這個程序就會喚醒worker線程,這個線程在按鈕上顯示工作狀態:等待(Waiting)還是正在工作(Working)。當按鈕被按下時,worker線程正在工作,那么對線程不產生影響。當run函數再次循環到mycond.wait()時,線程阻塞并等待。當按鈕再被按下時,觸發slotClicked()函數運行,喚醒等待的線程。

  1. #include <qapplication.h> 
  2. #include <qpushbutton.h> // 全局條件變量  
  3. QWaitCondition mycond; // Worker類實現  
  4. class Worker : public QPushButton, public QThread{  
  5.     Q_OBJECT public:    Worker(QWidget *parent = 0, const char *name = 0) : QPushButton(parent, name) {   
  6.        setText("Start Working");         // 將QPushButton繼承來的信號與槽slotClicked()連接起來  
  7.         connect(this, SIGNAL(clicked()), SLOT(slotClicked()));         // 調用從QThread繼承來的start()方法開始線程的執行   
  8.        QThread::start();  
  9.     }  
  10.  public slots:    void slotClicked()  {   // 喚醒等待這個條件變量的一個線程   
  11.        mycond.wakeOne();  
  12.     }   
  13. protected:    void run() //重載run函數    {   
  14.          while ( TRUE ) {            // 鎖定應用程序互斥鎖,并且設置窗口標題來表明我們正在等待開始工作  
  15.             qApp->lock();  
  16.             setCaption( "Waiting" );  
  17.             qApp->unlock();             // 等待直到我們被告知可以繼續   
  18.            mycond.wait();            // 如果到了這里,表示我們已經被另一個線程喚醒   
  19.            qApp->lock();  
  20.             setCaption( "Working!" );// 設置標題,表示正在工作   
  21.            qApp->unlock();   
  22.      }  
  23.     }  
  24. };   
  25. int main( int argc, char **argv ){  
  26.     QApplication app( argc, argv );     // 創建一個worker  
  27.     Worker firstworker( 0, "worker" );  
  28.      app.setMainWidget( &worker ); //將worker設置為應用程序的主窗口  
  29.     worker.show();    
  30.    return app.exec();  

當進行線程編程時,需要注意的一些事項:

(1)在持有Qt庫互斥量時不要做任何阻塞操作。這將凍結事件循環。

(2)確認你鎖定一個遞歸QMutex的次數等于解鎖的次數,不能多也不能少。

(3)在調用除了Qt容器和工具類外的任何東西之前鎖定Qt應用程序互斥量。

(4)謹防隱含的共享類,如果你需要在線程之間指定它們,你應該用detach()分離它們。

(5)小心沒有被設計成線程安全的Qt類,例如,QPtrList的API接口不是線程安全的,并且如果不同的線程需要遍歷一個QPtrList,它們應該在調用QPtrList::first()之前鎖住,在到達終點后解鎖。

(6)確信僅在GUI線程中創建繼承自QWidget、QTimer和QSocketNotifier的對象。在一些平臺上,創建在線程中而不是GUI線程的對象永遠不會接收到底層窗口系統的事件。

(7)和上面很相似,只在GUI線程中使用QNetwork類。因為所有的QNetwork類都是異步的,沒必要把QSocket用在多線程中。

(8)永遠不要嘗試在不是GUI線程線程中調用processEvents()函數。這也包括QDialog::exec()、QPopupMenu::exec()、QApplication::processEvents()和其它一些函數。

(9)在你的應用程序中,不要把普通的Qt庫和支持線程Qt庫混合使用。這意味著如果你的程序使用了支持線程Qt庫,你就不能連接普通的Qt庫、動態的載入普通Qt庫或者動態地連接其它依賴普通Qt庫的庫或者插件。在一些系統上,這樣做會導致Qt庫中使用的靜態數據崩潰。

小結:QT核心編程之Qt線程 的內容介紹完了,希望本節內容隨你有所幫助,如果需要更多資料請參考編輯推薦。

【編輯推薦】

QT核心編程之Qt模板庫(1)

QT核心編程之集合類 (2)

QT核心編程之鼠標拖放 (4)

QT核心編程之鍵盤焦點 (5)

QT核心編程之會話管理 (6)

QT核心編程之調試技術 (7)

責任編輯:zhaolei 來源: 互聯網
相關推薦

2011-06-22 09:40:32

QT 模板庫 模板

2011-06-22 09:58:04

QT 集合類

2011-06-22 10:27:32

QT 鍵盤 焦點

2011-06-22 10:39:56

QT 會話管理

2011-06-22 10:20:11

QT 鼠標 拖放

2011-06-22 10:45:21

QT 調試

2011-06-22 16:08:40

Qt 多線程 事件循環

2011-06-13 10:03:19

Qt 多線程 編程

2011-06-22 16:02:37

Qt 多線程 重入

2011-06-16 10:38:13

Qt多線程編程

2011-06-20 13:43:08

Qt Socket 線程

2011-06-17 14:41:56

Qt

2011-06-30 17:51:17

QT 元類型 線程

2011-06-22 16:18:23

QT 多線程 QSocket

2011-06-24 15:30:22

QT 皮膚 QSS

2011-06-13 16:51:19

Qt Socket

2011-06-10 12:44:09

2011-06-22 15:50:45

QT 線程

2011-06-22 15:09:34

Qt 線程 sleep

2011-06-08 15:06:09

Qt 教程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 最新中文字幕一区 | 欧美日韩一区二区在线播放 | 国产精品一区二区av | 亚洲久草| 国产精品激情小视频 | 欧美一区视频 | 日韩精品一区二区三区中文在线 | 青青久久| 亚洲精品久久久久中文字幕欢迎你 | 日本在线黄色 | 福利网站在线观看 | 日本精品视频一区二区三区四区 | 亚洲精品成人av久久 | 91国内外精品自在线播放 | www.久| 色爱综合网 | 91资源在线播放 | 欧美高清一区 | 一区二区三区亚洲 | 亚洲综合激情 | 免费看国产片在线观看 | 久久9精品 | 谁有毛片 | 国产乱码精品一区二区三区忘忧草 | 日韩av高清在线 | 免费看啪啪网站 | 久久爱黑人激情av摘花 | 黄色毛片免费 | 亚洲精品电影网在线观看 | 久久久在线视频 | 中文字幕一区在线观看视频 | 黄色一级大片在线免费看产 | 91性高湖久久久久久久久_久久99 | 国产成人精品区一区二区不卡 | 97日韩精品 | 三级成人在线 | 国产一区| 波多野结衣一区二区 | 成人午夜性成交 | 超碰导航| av中文在线播放 |