程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> lesson15-QT多線程

lesson15-QT多線程

編輯:JAVA綜合教程

lesson15-QT多線程


一、什麼是線程
1、線程
進程:一個正在執行的程序,它是資源分配的最小單位
線程:程序執行的最小單位

進程出現了很多弊端,一是由於進程是資源擁有者,創建、撤消與切換存在較大的時空開銷,因此需要引入輕型進程;二是由於對稱多處理機(SMP)出現,可以滿足多個運行單位,而多個進程並行開銷過大。

2、線程的術語
並發是指在同一時刻,只能有一條指令執行,但多個進程指令被快速輪換執行,使得在宏觀上具有多個進程同時執行的效果。
看起來同時發生

並行是指在同一時刻,有多條指令在多個處理器上同時執行。
真正的同時發生

同步:彼此有依賴關系的調用不應該“同時發生”,而同步就是要阻止那些“同時發生”的事情
異步的概念和同步相對,任何兩個彼此獨立的操作是異步的,它表明事情獨立的發生

3、線程的優勢
1)、在多處理器中開發程序的並行性
2)、在等待慢速IO操作時,程序可以執行其他操作,提高並發性
3)、模塊化的編程,能更清晰的表達程序中獨立事件的關系,結構清晰
4)、占用較少的系統資源

多線程不一定要多處理器
GUI程序中經常會使用多線程技術,一個線程用來響應界面,而其他線程就可以在後台處理冗長的操作
Qt的元對象系統支持不同線程中的對象使用信號和槽機制通信




二、QT多線程
Qt中使用多線程是非常簡單的,只要子類話QThread就可以了,在QThread中有一個protected類型的run函數,重寫run函數就可以實現多線程。
1、QT線程
Qt中使用多線程是非常簡單的,只要子類化QThread,然後重寫run函數就可以實現多線程

class MyThread:public Thread
{
public:
MyThread();
protected:
void run();
private:
volatile boolean stopped;
}

run函數是通過線程的start方法啟動的,線程還有isRunning方法來判斷是否在運行,terminate方法結束線程


2、線程同步之信號量
信號量使線程不需要忙碌的等待,是對mutex的一種擴展。使用信號量可以保證兩個關鍵代碼不會並發。在進入一段關鍵代碼時,線程必須獲取信號量,退出時必須釋放。信號量可以同時由多個線程訪問。

Qt的信號量QSemaphore類:
acquire()用來獲取資源,free()用來釋放資源

生產者和消費者的例子,生產者生產的時候需要確保有足夠的空間,消費者消費的時候要確保空間裡有資源
QSemaphore freeByte(100) 生產有有100個空間
QSemaphore useByte(0)消費者沒有資源
producer
{
freeByte.acquire()
byte = n
useByte.release()
}
consumer
{
useByte.acquire()
printf byte
freeByte.release()
}


3、線程同步之條件變量
QWaitCondition允許線程在一定條件下喚醒其他的線程,這樣也可以是線程不必忙碌的等待,條件變量要配合互斥量來使用

QMutex mutex; QWaitCondition condition;
condition.wait(&mutex)
condition.wakeAll()
wait函數將互斥量解鎖,並在此等待,此函數返回之前會將互斥量重新枷鎖。
wakeAll函數會將所有等待該互斥量的線程喚醒


4、線程優先級
實際任務可能會讓某個線程先運行,那麼就需要設置線程優先級。
setPriority函數可以設置線程的優先級,或者在線程啟動的時候在start函數傳入線程的優先級


三、實例
1、多線程
  1. #ifndef MYTHREAD_H
  2. #define MYTHREAD_H

  3. #include <QThread>

  4. class MyThread : public QThread
  5. {
  6. Q_OBJECT
  7. public:
  8. MyThread();
  9. void stop();
  10. volatile bool stopped;
  11. protected:
  12. void run();
  13. };
  14. #endif
  1. #include "myThread.h"
  2. #include <QtDebug>

  3. MyThread::MyThread()
  4. {
  5. stopped = false;
  6. }

  7. void MyThread::run()
  8. {
  9. int i=0;
  10. while(!stopped)
  11. {
  12. qDebug()<<"thread id:"<QThread::currentThreadId()<<":"<<i;
  13. i++;
  14. sleep(2);
  15. }
  16. stopped = false;
  17. }

  18. void MyThread::stop()
  19. {
  20. stopped = true;
  21. }

2、信號量

  1. #ifndef PRODUCER_H
  2. #define PRODUCER_H

  3. #include <QThread>

  4. class Producer : public QThread
  5. {
  6. Q_OBJECT
  7. public:
  8. Producer();
  9. protected:
  10. void run();
  11. };

  12. #endif

  1. #ifndef CONSUMER_H
  2. #define CONSUMER_H

  3. #include <QThread>

  4. class Consumer : public QThread
  5. {
  6. Q_OBJECT
  7. public:
  8. Consumer();
  9. protected:
  10. void run();
  11. };

  12. #endif

  1. #include "producer.h"
  2. #include "consumer.h"
  3. #include <QDebug>
  4. #include <QSemaphore>

  5. #define SIZE 50
  6. QSemaphore freeByte(SIZE);
  7. QSemaphore useByte(0);

  8. Producer::Producer()
  9. {

  10. }
  11. void Producer::run()
  12. {
  13. for(int i=0; i<SIZE; i++)
  14. {
  15. freeByte.acquire();
  16. qDebug()<<"produer:"<<i;
  17. useByte.release();
  18. sleep(1);
  19. }
  20. }
  21. Consumer::Consumer()
  22. {

  23. }
  24. void Consumer::run()
  25. {
  26. for(int i=0; i<SIZE; i++)
  27. {
  28. useByte.acquire();
  29. qDebug()<<"consumer:"<<i;
  30. freeByte.release();
  31. sleep(2);
  32. }
  33. }


3、條件變量

  1. #ifndef THREAD_H
  2. #define THREAD_H

  3. #include<QThread>

  4. class Producer : public QThread
  5. {
  6. Q_OBJECT
  7. public:
  8. Producer();
  9. protected:
  10. void run();
  11. };

  12. class Consumer : public QThread
  13. {
  14. Q_OBJECT
  15. public:
  16. Consumer();
  17. protected:
  18. void run();
  19. };

  20. #endif

  1. #include "thread.h"
  2. #include <QDebug>
  3. #include <QMutex>
  4. #include <QWaitCondition>

  5. QMutex mutex;
  6. QWaitCondition empty, full;
  7. int num=0;
  8. int buffer[50];
  9. int useByte=0;


  10. Producer::Producer()
  11. {

  12. }
  13. void Producer::run()
  14. {
  15. for(int i=0; i<50; i++)
  16. {
  17. mutex.lock();
  18. if(useByte==50)
  19. empty.wait(&mutex);
  20. num++;
  21. buffer[i] = num;
  22. qDebug()<<"producer:"<<num;
  23. useByte++;
  24. full.wakeAll();
  25. mutex.unlock();
  26. sleep(1);
  27. }
  28. }
  29. Consumer::Consumer()
  30. {

  31. }
  32. void Consumer::run()
  33. {
  34. for(int i=0; i<50; i++)
  35. {
  36. mutex.lock();
  37. if(useByte==0)
  38. full.wait(&mutex);
  39. qDebug()<<"consumer"<<buffer[i];
  40. useByte--;
  41. empty.wakeAll();
  42. mutex.unlock();
  43. sleep(2);
  44. }
  45. }



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved