How to share data between threads using QThread
-
I'm trying to learn how to share data between threads using
QThread
.In my code below
when I try to print the value ofworker_str
sometimes i get an exception in the fileqdebug.cpp
:Exception thrown: read access violation. **p** was 0x111011101110111.
and sometimes it prints
worker_str
as""
.What I'm doing wrong? also, I should call
thread->quit();
whenever I don't need that thread running anymore?
#include "worker.h" App::App(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); QThread* thread = new QThread(); Worker* worker = new Worker(); worker->moveToThread(thread); QString str = "hello world"; connect(thread, &QThread::started, worker, [worker, str] { worker->test(str); }); connect(worker, &Worker::finished, thread, [worker, thread] { qDebug() << "worker_str: " << worker->worker_str; thread->quit(); }); connect( worker, &Worker::finished, worker, &Worker::deleteLater); connect( thread, &QThread::finished, thread, &QThread::deleteLater); thread->start(); }
//worker.h class Worker : public QObject { Q_OBJECT public: Worker() {}; ~Worker() {}; QString worker_str; public slots: void test(QString str) { worker_str = str; qDebug() << "WORKER: str: " << str; emit finished(); }; signals: void finished(); };
-
Your Worker object is already gone when you try to access it in your slot. You can see this when using a debugger and setting a breakpoint in the lambda and the dtor of Worker or use a memory checker tool like e.g. valgrind.
class Worker : public QObject { Q_OBJECT public: ~Worker() { qWarning() << "DTOR" << this; } void test(QString str) { worker_str = str; qDebug() << "WORKER: str: " << str << this; emit finished(); } QString worker_str; signals: void finished(); }; class App : public QMainWindow { Q_OBJECT public: App(QWidget *parent = nullptr) : QMainWindow(parent) { QThread* thread = new QThread(); Worker* worker = new Worker(); worker->moveToThread(thread); QString str = "hello world"; connect(thread, &QThread::started, worker, [worker, str] { worker->test(str); }); connect(worker, &Worker::finished, thread, [worker, thread] { qWarning() << "worker_str: " << worker->worker_str; thread->quit(); }); connect(worker, &Worker::finished, worker, &Worker::deleteLater); connect(thread, &QThread::finished, thread, &QThread::deleteLater); connect(thread, &QThread::finished, thread, &QCoreApplication::quit); thread->start(); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); App app; return a.exec(); } #include "main.moc"
-
Your Worker object is already gone when you try to access it in your slot. You can see this when using a debugger and setting a breakpoint in the lambda and the dtor of Worker or use a memory checker tool like e.g. valgrind.
class Worker : public QObject { Q_OBJECT public: ~Worker() { qWarning() << "DTOR" << this; } void test(QString str) { worker_str = str; qDebug() << "WORKER: str: " << str << this; emit finished(); } QString worker_str; signals: void finished(); }; class App : public QMainWindow { Q_OBJECT public: App(QWidget *parent = nullptr) : QMainWindow(parent) { QThread* thread = new QThread(); Worker* worker = new Worker(); worker->moveToThread(thread); QString str = "hello world"; connect(thread, &QThread::started, worker, [worker, str] { worker->test(str); }); connect(worker, &Worker::finished, thread, [worker, thread] { qWarning() << "worker_str: " << worker->worker_str; thread->quit(); }); connect(worker, &Worker::finished, worker, &Worker::deleteLater); connect(thread, &QThread::finished, thread, &QThread::deleteLater); connect(thread, &QThread::finished, thread, &QCoreApplication::quit); thread->start(); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); App app; return a.exec(); } #include "main.moc"
@Christian-Ehrlicher I get the same exception when trying your code
Your Worker object is already gone when you try to access it in your slot.
Could help pointing the proper way to read it then?
-
@Christian-Ehrlicher I get the same exception when trying your code
Your Worker object is already gone when you try to access it in your slot.
Could help pointing the proper way to read it then?
@n34rt said in How to share data between threads using QThread:
Could help pointing the proper way to read it then?
Either pass the value poer signal/slot out of the thread or don't delete the worker in an own connect() but in the readout function.
-
@n34rt said in How to share data between threads using QThread:
Could help pointing the proper way to read it then?
Either pass the value poer signal/slot out of the thread or don't delete the worker in an own connect() but in the readout function.
or don't delete the worker in an own connect() but in the readout function.
connect(worker, &Worker::finished, thread, [worker, thread] { qWarning() << "worker_str: " << worker->worker_str; thread->quit(); thread->deleteLater(); worker->deleteLater(); connect(thread, &QThread::finished, thread, &QCoreApplication::quit); });
like this?
Is this line really necessary?
connect(thread, &QThread::finished, thread, &QCoreApplication::quit);
I mean, do i need to call
QCoreApplication::quit
for that thread? -
or don't delete the worker in an own connect() but in the readout function.
connect(worker, &Worker::finished, thread, [worker, thread] { qWarning() << "worker_str: " << worker->worker_str; thread->quit(); thread->deleteLater(); worker->deleteLater(); connect(thread, &QThread::finished, thread, &QCoreApplication::quit); });
like this?
Is this line really necessary?
connect(thread, &QThread::finished, thread, &QCoreApplication::quit);
I mean, do i need to call
QCoreApplication::quit
for that thread?@n34rt said in How to share data between threads using QThread:
I mean, do i need to call
QCoreApplication::quit
for that thread?It's needed to properly end my testcase.
-
@n34rt said in How to share data between threads using QThread:
I mean, do i need to call
QCoreApplication::quit
for that thread?It's needed to properly end my testcase.
@Christian-Ehrlicher I'm asking if I do need to call it whenever I start a thread and don't need it anymore
-
@Christian-Ehrlicher I'm asking if I do need to call it whenever I start a thread and don't need it anymore
@n34rt said in How to share data between threads using QThread:
I'm asking if I do need to call it whenever I start a thread and don't need it anymore
If you want to quit your application after your thread finished yes - but I doubt so.
-
@n34rt said in How to share data between threads using QThread:
I'm asking if I do need to call it whenever I start a thread and don't need it anymore
If you want to quit your application after your thread finished yes - but I doubt so.
@Christian-Ehrlicher I see thank you, sorry im a newbie about threading
Either pass the value poer signal/slot out of the thread
Could you point how is it?
-
@Christian-Ehrlicher I see thank you, sorry im a newbie about threading
Either pass the value poer signal/slot out of the thread
Could you point how is it?
@n34rt said in How to share data between threads using QThread:
Could you point how is it?
Create a signal with a parameter of the type you want to pass and then a slot with same parameter type. Connect the signal and slot. Each time you want to pass the parameter emit the signal and give it the parameter.