Explain the sharing of data between Qt threads (using Signal/slot to pass data, passing signals between threads will return immediately, but can also be changed via Connect)

Source: Internet
Author: User
Tags emit

Use shared memory. Even with a variable that can be shared by two threads (such as a global variable), two threads can access and modify the variable to achieve the purpose of sharing the data.

Qt thread sharing data is the content of this article, many do not say, first to chew the content. There are two main ways of sharing data between QT threads:

Use shared memory. Even with a variable that can be shared by two threads (such as a global variable), two threads can access and modify the variable to achieve the purpose of sharing the data;

Use the singal/slot mechanism to pass data from one thread to another thread.

The first approach is common in all programming languages, while the second is the unique way of QT, which is mainly learned in this way:

Transferring signal between threads is not the same as passing signal within a thread. When signal is passed within a thread, the emit statement invokes all the connected slots directly and waits until all slots are processed, and the slots are placed in the queue when signal is passed between the threads (queue), and emit the signal returns immediately; The queue mechanism is used between threads, and the direct mechanism is used within threads, but these default mechanisms can be changed in 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
Public:
Textdevice ();
The void run ();
void Stop ();
Public Slots:
void Write (const qstring& text);
Private:
M_count int;
Qmutex M_mutex;
19};
#endif//Textdevice_h
21st
22
//textdevice.cpp
#include <QMutexLocker>
#include <QDebug>
#include <QString>
#include "TextDevice.h"
Textdevice::textdevice () {
M_count = 0;
30}
void Textdevice::run () {
exec ();
33}
Textdevice::stop void () {
+ Quit ();
36}
PNS void Textdevice::write (const qstring& text) {
Qmutexlocker Locker (&m_mutex);
Qdebug () << QString ("Call% 1:%2"). Arg (m_count++). Arg (text);
40}
41
//textthread.h
#ifndef Textthread_h
#define Textthread_h
#include <QThread>
#include <QString>
Class Textthread:public Qthread {
Q_object
Public:
Textthread (const qstring& text);
N/a void run ();
N-void Stop ();
Signals:
WRITETEXT void (const qstring&);
Private:
QString M_text;
m_stop bool;
58};
#endif//Textthread_h
60
//textthread.cpp
#include "TextThread.h"
Textthread::textthread (const qstring& text): Qthread () {
M_text = text;
M_stop = false;
66}
Textthread::stop void () {
M_stop = true;
69}
+ void Textthread::run () {
while (!m_stop) {
Emit WRITETEXT (M_text);
Sleep (1);
74}
75}
76
//main.cpp
#include <QApplication>
#include <QMessageBox>
#include "TextDevice.h"
Bayi #include "TextThread.h"
82
ARGC int main (int, char** argv) {
Qapplication app (argc, argv);
85//Start thread
Textdevice device;
Textthread foo ("foo"), Bar ("Bar");
88//Connect two threads using Signal/slot
Qobject::connect (&foo, SIGNAL (WRITETEXT (const qstring&)), &device, SLOT (write (const qstring&)));
Qobject::connect (&bar, SIGNAL (WRITETEXT (const qstring&)), &device, SLOT (write (const qstring&)));
91//Start thread
Foo.start ();
Bar.start ();
94 Device.start ();
Qmessagebox::information (0, "threading", "Close me to stop.");
96//Stop Thread
Foo.stop ();
98 bar.stop ();
Device.stop ();
100//Waiting for thread to end
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>
#include <QString>
111 #include <QMutex>
Qthread class Textdevice:public {
113 Q_object
Public:
Textdevice ();
The void run ();
117 void Stop ();
118 Public Slots:
119 void Write (const qstring& text);
Private:
121 int M_count;
122 Qmutex M_mutex;
123};
124 #endif//Textdevice_h
125
126
127//textdevice.cpp
#include <QMutexLocker>
129 #include <QDebug>
#include <QString>
131 #include "TextDevice.h"
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>
#include <QString>
151 class Textthread:public Qthread {
Q_object
153 Public:
154 Textthread (const qstring& text);
155 void Run ();
156 void Stop ();
157 Signals:
158 void WriteText (const qstring&);
159 Private:
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//Start thread
189 Textdevice device;
Textthread foo ("foo"), Bar ("Bar");
191//Connect two threads using 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//Start thread
195 Foo.start ();
196 Bar.start ();
197 Device.start ();
198 qmessagebox::information (0, "threading", "Close me to stop.");
199//Stop thread
Foo.stop ();
201 Bar.stop ();
202 device.stop ();
203//Waiting for thread to end
204 device.wait ();
205 foo.wait ();
206 bar.wait ();
207 return 0;
208}

The example code above shows that two threads are transferring information of type qstring. such as qstring, such as the QT itself defined by the type, direct transfer can. But it's not that simple if you're defining a type that you want to use Signal/slot to pass. If used directly, the following error is generated:

  

Cause: When a signal is placed in the queue (queued), its parameters (arguments) are also put together in the queue (queued up), which means that the parameters need to be copied and stored in the queue before being transferred to the slot In order to be able to store these parameters in the queue (argument), QT needs to go to construct, destruct, copy these objects, and in order for Qt to know how to do these things, The type of the parameter needs to be registered with Qregistermetatype (as described in the error prompt)

Steps: (Take the custom Textandnumber type as an example)

Customize a type, at the top of this type contains: #include <QMetaType>

After the type definition is complete, join the declaration: Q_declare_metatype (Textandnumber);

Register this type:qregistermetatype<textandnumber> ("Textandnumber") in the main () function.

If you also want to use this type of reference, you can also register:qregistermetatype<textandnumber> ("textandnumber&");

1 view plaincopy to Clipboardprint?
2//textandnumber.h
3 #ifndef Textandnumber_h
4 #define Textandnumber_h
5 #include <QMetaType>
6//must contain Qmetatype, otherwise the following error will occur:
7//error:expected constructor, destructor, or type conversion before '; ' token
8 #include <QString>
9 class Textandnumber {
Public:
Textandnumber ();
Textandnumber (int, QString);
int count ();
QString text ();
Private:
M_count int;
QString M_text;
18};
Q_declare_metatype (Textandnumber);
#endif//Textandnumber_h
21st
//textandnumber.cpp
#include "TextAndNumber.h"
Textandnumber::textandnumber () {
25}
Textandnumber::textandnumber (int count, QString text) {
M_count = count;
M_text = text;
29}
int Textandnumber::count () {
return m_count;
32}
QString Textandnumber::text () {
M_text return;
35}
36
Panax Notoginseng//textdevice.h
#ifndef Textdevice_h
Textdevice_h #define
#include <QThread>
#include <QDebug>
#include <QString>
#include "TextAndNumber.h"
Qthread class Textdevice:public {
Q_object
Public:
Textdevice ();
The void run ();
$ void Stop ();
Public Slots:
N/a void write (textandnumber& tran);
Private:
M_count int;
54};
#endif//Textdevice_h
56
//textdevice.cpp
#include "TextDevice.h"
Textdevice::textdevice (): Qthread () {
M_count = 0;
61}
Textdevice::run void () {
A. exec ();
64}
Textdevice::stop void () {
$ quit ();
67}
Textdevice::write (textandnumber& Tran) {
Qdebug () << QString ("Call%1 (% 3):%2"). Arg (m_count++). Arg (Tran.text ()). Arg (Tran.count ());
70}
71
//textthread.h
Textthread_h #ifndef
Textthread_h #define
#include <QThread>
#include <QString>
#include "TextAndNumber.h"
Textthread:public class Qthread {
Q_object
Public:
Bayi Textthread (const qstring& text);
();
The void Stop ();
Signals:
WRITETEXT (textandnumber& Tran);
Private:
QString M_text;
M_count int;
m_stop bool;
90};
91
#endif//Textthread_h
93
94//textthread.cpp
#include "TextThread.h"
Textthread::textthread (const qstring& text): Qthread () {
M_text = text;
98 m_stop = false;
M_count = 0;
100}
101 void Textthread::run () {
102 while (!m_stop) {
103 Textandnumber tn (m_count++, M_text);
104 Emit WRITETEXT (TN);
Sleep (1);
106}
107}
108 void Textthread::stop () {
109 M_stop = true;
110}
111
//main.cpp
113 #include <QApplication>
#include <QMessageBox>
#include "TextThread.h"
#include "TextDevice.h"
117 #include "TextAndNumber.h"
118 int Main (int argc, char *argv[])
119 {
Qapplication app (argc, argv);
121 qregistermetatype<textandnumber> ("Textandnumber");
122 qregistermetatype<textandnumber> ("textandnumber&");
123 Textdevice device;
124 textthread foo ("foo"), Bar ("Bar");
Qobject::connect (&foo, SIGNAL (WRITETEXT (textandnumber&)), &device, SLOT (write (textandnumber&)) );
126 Qobject::connect (&bar, SIGNAL (WRITETEXT (textandnumber&)), &device, SLOT (write (textandnumber&)) );
127 Device.start ();
Foo.start ();
129 Bar.start ();
Qmessagebox::information (0, "threading", "Click Me to Close");
131 Foo.stop ();
Bar.stop ();
133 Device.stop ();
134 foo.wait ();
135 bar.wait ();
136 device.wait ();
137 qdebug () << "Application end.";
138 return 0;
139}

Http://www.cnblogs.com/bingcaihuang/archive/2011/07/14/2106885.html

Explain the sharing of data between Qt threads (using Signal/slot to pass data, passing signals between threads will return immediately, but can also be changed via Connect)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.