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

詳解 Qt 線程間共享數據

移動開發
使用共享內存。即使用一個兩個線程都能夠共享的變量(如全局變量),這樣兩個線程都能夠訪問和修改該變量,從而達到共享數據的目的。

Qt 線程共享數據是本文介紹的內容,多的不說,先來啃內容。Qt線程共享數據主要有兩種方式:

使用共享內存。即使用一個兩個線程都能夠共享的變量(如全局變量),這樣兩個線程都能夠訪問和修改該變量,從而達到共享數據的目的;

使用singal/slot機制,把數據從一個線程傳遞到另外一個線程

***種辦法在各個編程語言都使用普遍,而第二種方式倒是QT的特有方式,下面主要學習一下這種方式:

在線程之間傳遞signal與在一個線程內傳遞signal是不一樣的。在一個線程內傳遞signal時,emit語句會直接調用所有連接的slot并等待到所有slot被處理完;在線程之間傳遞signal時,slot會被放到隊列中(queue),而emit這個signal后會馬上返回;默認情況,線程之間使用queue機制,而線程內使用direct機制,但在connect中可以改變這些默認的機制。

  1. view plaincopy to clipboardprint?  
  2. //TextDevice.h    
  3. #ifndef TEXTDEVICE_H    
  4. #define TEXTDEVICE_H    
  5. #include <QThread>    
  6. #include <QString>    
  7. #include <QMutex>     
  8. class TextDevice : public QThread {     
  9.     Q_OBJECT     
  10. public:     
  11.     TextDevice();     
  12.     void run();     
  13.     void stop();     
  14. public slots:     
  15.     void write(const QString& text);     
  16. private:     
  17.     int m_count;     
  18.     QMutex m_mutex;     
  19. };    
  20. #endif // TEXTDEVICE_H     
  21.     
  22.     
  23. //TextDevice.cpp    
  24. #include <QMutexLocker>    
  25. #include <QDebug>    
  26. #include <QString>    
  27. #include "TextDevice.h"     
  28. TextDevice::TextDevice() {     
  29.     m_count = 0;     
  30. }     
  31. void TextDevice::run() {     
  32.     exec();     
  33. }     
  34. void TextDevice::stop() {     
  35.     quit();     
  36. }     
  37. void TextDevice::write(const QString& text) {     
  38.     QMutexLocker locker(&m_mutex);     
  39.     qDebug() << QString("Call %1: %2").arg(m_count++).arg(text);     
  40. }     
  41.     
  42. //TextThread.h    
  43. #ifndef TEXTTHREAD_H    
  44. #define TEXTTHREAD_H    
  45. #include <QThread>    
  46. #include <QString>     
  47. class TextThread : public QThread {     
  48.     Q_OBJECT     
  49. public:     
  50.     TextThread(const QString& text);     
  51.     void run();     
  52.     void stop();     
  53. signals:     
  54.     void writeText(const QString&);     
  55. private:     
  56.     QString m_text;     
  57.     bool m_stop;     
  58. };    
  59. #endif // TEXTTHREAD_H     
  60.     
  61. //TextThread.cpp    
  62. #include "TextThread.h"     
  63. TextThread::TextThread(const QString& text) : QThread() {     
  64.     m_text = text;     
  65.     m_stop = false;     
  66. }     
  67. void TextThread::stop() {     
  68.     m_stop = true;     
  69. }     
  70. void TextThread::run() {     
  71.     while(!m_stop) {     
  72.         emit writeText(m_text);     
  73.         sleep(1);     
  74.     }     
  75. }     
  76.     
  77. //main.cpp    
  78. #include <QApplication>    
  79. #include <QMessageBox>    
  80. #include "TextDevice.h"    
  81. #include "TextThread.h"     
  82.     
  83. int main(int argc, char** argv) {     
  84.     QApplication app(argc, argv);     
  85.     //啟動線程     
  86.     TextDevice device;     
  87.     TextThread foo("foo"), bar("bar");     
  88.     //把兩個線程使用signal/slot連接起來     
  89.     QObject::connect(&foo, SIGNAL(writeText(const QString&)), &device, SLOT(write(const QString&)));     
  90.     QObject::connect(&bar, SIGNAL(writeText(const QString&)), &device, SLOT(write(const QString&)));     
  91.     //啟動線程     
  92.     foo.start();     
  93.     bar.start();     
  94.     device.start();     
  95.     QMessageBox::information(0, "Threading", "Close me to stop.");     
  96.     //停止線程     
  97.     foo.stop();     
  98.     bar.stop();     
  99.     device.stop();     
  100.     //等待線程結束     
  101.     device.wait();     
  102.     foo.wait();     
  103.     bar.wait();     
  104.     return 0;     
  105. }    
  106. //TextDevice.h  
  107. #ifndef TEXTDEVICE_H  
  108. #define TEXTDEVICE_H  
  109. #include <QThread> 
  110. #include <QString> 
  111. #include <QMutex> 
  112. class TextDevice : public QThread {  
  113.     Q_OBJECT  
  114. public:  
  115.     TextDevice();  
  116.     void run();  
  117.     void stop();  
  118. public slots:  
  119.     void write(const QString& text);  
  120. private:  
  121.     int m_count;  
  122.     QMutex m_mutex;  
  123. };  
  124. #endif // TEXTDEVICE_H  
  125.  
  126.  
  127. //TextDevice.cpp  
  128. #include <QMutexLocker> 
  129. #include <QDebug> 
  130. #include <QString> 
  131. #include "TextDevice.h"  
  132. TextDevice::TextDevice() {  
  133.     m_count = 0;  
  134. }  
  135. void TextDevice::run() {  
  136.     exec();  
  137. }  
  138. void TextDevice::stop() {  
  139.     quit();  
  140. }  
  141. void TextDevice::write(const QString& text) {  
  142.     QMutexLocker locker(&m_mutex);  
  143.     qDebug() << QString("Call %1: %2").arg(m_count++).arg(text);  
  144. }  
  145.  
  146. //TextThread.h  
  147. #ifndef TEXTTHREAD_H  
  148. #define TEXTTHREAD_H  
  149. #include <QThread> 
  150. #include <QString> 
  151. class TextThread : public QThread {  
  152.     Q_OBJECT  
  153. public:  
  154.     TextThread(const QString& text);  
  155.     void run();  
  156.     void stop();  
  157. signals:  
  158.     void writeText(const QString&);  
  159. private:  
  160.     QString m_text;  
  161.     bool m_stop;  
  162. };  
  163. #endif // TEXTTHREAD_H  
  164.  
  165. //TextThread.cpp  
  166. #include "TextThread.h"  
  167. TextThread::TextThread(const QString& text) : QThread() {  
  168.     m_text = text;  
  169.     m_stop = false;  
  170. }  
  171. void TextThread::stop() {  
  172.     m_stop = true;  
  173. }  
  174. void TextThread::run() {  
  175.     while(!m_stop) {  
  176.         emit writeText(m_text);  
  177.         sleep(1);  
  178.     }  
  179. }  
  180.  
  181. //main.cpp  
  182. #include <QApplication> 
  183. #include <QMessageBox> 
  184. #include "TextDevice.h"  
  185. #include "TextThread.h"  
  186. int main(int argc, char** argv) {  
  187.     QApplication app(argc, argv);  
  188.     //啟動線程  
  189.     TextDevice device;  
  190.     TextThread foo("foo"), bar("bar");  
  191.     //把兩個線程使用signal/slot連接起來  
  192.     QObject::connect(&foo, SIGNAL(writeText(const QString&)), &device, SLOT(write(const QString&)));  
  193.     QObject::connect(&bar, SIGNAL(writeText(const QString&)), &device, SLOT(write(const QString&)));  
  194.     //啟動線程  
  195.     foo.start();  
  196.     bar.start();  
  197.     device.start();  
  198.     QMessageBox::information(0, "Threading", "Close me to stop.");  
  199.     //停止線程  
  200.     foo.stop();  
  201.     bar.stop();  
  202.     device.stop();  
  203.     //等待線程結束  
  204.     device.wait();  
  205.     foo.wait();  
  206.     bar.wait();  
  207.     return 0;  

#p#

上面例子代碼可以看出兩個線程之間傳送了類型為QString的信息。像QString等這些QT本身定義的類型,直接傳送即可。但如果是自己定義的類型如果想使用signal/slot來傳遞的話,則沒有這么簡單。直接使用的話,會產生下面這種錯誤:

  1. QObject::connect: Cannot queue arguments of type 'TextAndNumber' (Make sure 'TextAndNumber' is registed using qRegisterMetaType().) 

原因:當一個signal被放到隊列中(queued)時,它的參數(arguments)也會被一起一起放到隊列中(queued起來),這就意味著參數在被傳送到slot之前需要被拷貝、存儲在隊列中(queue)中;為了能夠在隊列中存儲這些參數(argument),Qt需要去construct、destruct、copy這些對象,而為了讓Qt知道怎樣去作這些事情,參數的類型需要使用qRegisterMetaType來注冊(如錯誤提示中的說明)

步驟:(以自定義TextAndNumber類型為例)

自定一種類型,在這個類型的頂部包含:#include <QMetaType>

在類型定義完成后,加入聲明:Q_DECLARE_METATYPE(TextAndNumber);

在main()函數中注冊這種類型:qRegisterMetaType<TextAndNumber>("TextAndNumber");

如果還希望使用這種類型的引用,可同樣要注冊:qRegisterMetaType<TextAndNumber>("TextAndNumber&");

  1. view plaincopy to clipboardprint?  
  2. //TextAndNumber.h     
  3. #ifndef TEXTANDNUMBER_H     
  4. #define TEXTANDNUMBER_H     
  5. #include <QMetaType>     
  6. //必須包含QMetaType,否則會出現下面錯誤:     
  7. //error: expected constructor, destructor, or type conversion before ‘;’ token     
  8. #include <QString>     
  9. class TextAndNumber {     
  10. public:     
  11.     TextAndNumber();     
  12.     TextAndNumber(int, QString);     
  13.     int count();     
  14.     QString text();     
  15. private:     
  16.     int m_count;     
  17.     QString m_text;     
  18. };     
  19. Q_DECLARE_METATYPE(TextAndNumber);     
  20. #endif // TEXTANDNUMBER_H     
  21.     
  22. //TextAndNumber.cpp     
  23. #include "TextAndNumber.h"     
  24. TextAndNumber::TextAndNumber() {     
  25. }     
  26. TextAndNumber::TextAndNumber(int count, QString text) {     
  27.     m_count = count;     
  28.     m_text = text;     
  29. }     
  30. int TextAndNumber::count() {     
  31.     return m_count;     
  32. }     
  33. QString TextAndNumber::text() {     
  34.     return m_text;     
  35. }     
  36.     
  37. //TextDevice.h     
  38. #ifndef TEXTDEVICE_H     
  39. #define TEXTDEVICE_H     
  40. #include <QThread>     
  41. #include <QDebug>     
  42. #include <QString>     
  43. #include "TextAndNumber.h"     
  44. class TextDevice : public QThread {     
  45.     Q_OBJECT     
  46. public:     
  47.     TextDevice();     
  48.     void run();     
  49.     void stop();     
  50. public slots:     
  51.     void write(TextAndNumber& tran);     
  52. private:     
  53.     int m_count;     
  54. };     
  55. #endif // TEXTDEVICE_H     
  56.     
  57. //TextDevice.cpp     
  58. #include "TextDevice.h"     
  59. TextDevice::TextDevice() : QThread() {     
  60.     m_count = 0;     
  61. }     
  62. void TextDevice::run() {     
  63.     exec();     
  64. }     
  65. void TextDevice::stop() {     
  66.     quit();     
  67. }     
  68. void TextDevice::write(TextAndNumber& tran) {     
  69.     qDebug() << QString("Call %1 (%3): %2").arg(m_count++).arg(tran.text()).arg(tran.count());     
  70. }     
  71.     
  72. //TextThread.h     
  73. #ifndef TEXTTHREAD_H     
  74. #define TEXTTHREAD_H     
  75. #include <QThread>     
  76. #include <QString>     
  77. #include "TextAndNumber.h"     
  78. class TextThread : public QThread {     
  79.     Q_OBJECT     
  80. public:     
  81.     TextThread(const QString& text);     
  82.     void run();     
  83.     void stop();     
  84. signals:     
  85.     void writeText(TextAndNumber& tran);     
  86. private:     
  87.     QString m_text;     
  88.     int m_count;     
  89.     bool m_stop;     
  90. };     
  91.     
  92. #endif // TEXTTHREAD_H     
  93.     
  94. //TextThread.cpp     
  95. #include "TextThread.h"     
  96. TextThread::TextThread(const QString& text) : QThread() {     
  97.     m_text = text;     
  98.     m_stop = false;     
  99.     m_count = 0;     
  100. }     
  101. void TextThread::run() {     
  102.     while(!m_stop) {     
  103.         TextAndNumber tn(m_count++, m_text);     
  104.         emit writeText(tn);     
  105.         sleep(1);     
  106.     }     
  107. }     
  108. void TextThread::stop() {     
  109.     m_stop = true;     
  110. }     
  111.     
  112. //main.cpp     
  113. #include <QApplication>     
  114. #include <QMessageBox>     
  115. #include "TextThread.h"     
  116. #include "TextDevice.h"     
  117. #include "TextAndNumber.h"     
  118. int main(int argc, char *argv[])     
  119. {     
  120.     QApplication app(argc, argv);     
  121.     qRegisterMetaType<TextAndNumber>("TextAndNumber");     
  122.     qRegisterMetaType<TextAndNumber>("TextAndNumber&");     
  123.     TextDevice device;     
  124.     TextThread foo("foo"), bar("bar");     
  125.     QObject::connect(&foo, SIGNAL(writeText(TextAndNumber&)), &device, SLOT(write(TextAndNumber&)));     
  126.     QObject::connect(&bar, SIGNAL(writeText(TextAndNumber&)), &device, SLOT(write(TextAndNumber&)));     
  127.     device.start();     
  128.     foo.start();     
  129.     bar.start();     
  130.     QMessageBox::information(0, "Threading", "Click me to close");     
  131.     foo.stop();     
  132.     bar.stop();     
  133.     device.stop();     
  134.     foo.wait();     
  135.     bar.wait();     
  136.     device.wait();     
  137.     qDebug() << "Application end.";     
  138.     return 0;     
  139. }   

小結:詳解 Qt 線程共享數據的內容介紹完了,希望本文對你有所幫助!

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

2020-12-14 08:43:56

線程進程資源

2011-07-01 13:03:32

QT 線程 串口

2023-10-26 08:16:20

C++線程

2025-01-07 12:58:28

2011-06-23 18:37:02

Qt 數據庫

2011-06-22 17:09:50

QT 進程 通信

2011-06-30 18:03:58

QT 多線程 服務器

2011-07-05 09:54:04

2011-07-01 14:06:57

Qt sqlite

2017-02-16 08:13:17

2020-08-10 08:28:19

ZeroMQCPython

2010-03-16 15:32:26

2011-06-24 10:05:51

QT 對象 父對象

2011-08-30 14:25:06

QT數據庫

2018-01-12 14:35:00

Linux進程共享內存

2011-06-22 10:12:08

Qt 線程

2011-06-20 17:33:58

Qt MeegoTouch Maemo

2011-06-28 15:01:01

Qt PIMPL

2011-07-01 10:35:20

QT 多線程 TCP

2021-03-05 07:38:52

C++線程編程開發技術
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品视频在线观看视频 | 亚洲视频1区 | 影视先锋av资源噜噜 | 一级黄色片在线免费观看 | 欧美日韩亚洲一区 | 成人在线免费观看av | 中文字幕一区在线观看视频 | 国产在线精品一区二区三区 | 欧美一区二区在线视频 | 国产精品久久精品 | 最新国产在线 | 亚洲一av| 亚洲天堂一区 | 国产精品1区2区3区 国产在线观看一区 | 久久精品亚洲 | 久久久综合色 | 色99视频| 亚洲一二三视频 | 欧美8一10sex性hd| 国产欧美精品区一区二区三区 | 精品免费视频 | 久久久久国产一区二区三区四区 | 蜜桃传媒一区二区 | 一区二区电影网 | 伊色综合久久之综合久久 | 国产精品美女久久久久久免费 | 日韩精品成人一区二区三区视频 | 99在线精品视频 | 亚洲欧洲国产视频 | 久久www免费视频 | 奇米视频777| 成人h视频在线观看 | www.天天操.com | 精品一区二区久久久久久久网站 | 久久久精品一区 | 欧美国产一区二区 | 日韩高清中文字幕 | 欧美午夜在线 | 日韩精品一区二区三区中文在线 | 在线国产一区二区 | 91极品视频|