Solved threads and created objects
-
UdpSocket::UdpSocket(QHostAddress *qha, QObject *parent) : QObject(parent) { QHostAddress *l_qha; QString qs; // set up addresses. l_qha = qha; qs = l_qha->toString(); m_addrMulticast.setAddress(qs); init(); QObject::connect(&m_timer, &QTimer::timeout, this, &UdpSocket::checkSockets); m_timer.start(3000); }
-
@SGaist said in threads and created objects:
Object belonging and thread affinity are different things.
I didn't realize that, but OK.
The message you had was because the destruction happened in the main thread.
So, how is this changed by creating worker on the heap?
-
@SGaist said in threads and created objects:
The message you had was because the destruction happened in the main thread.
Correct, I read it the other way and thought the timer was still in the main thread and was destructed in the other thread :)
-
Your object on the stack gets destroyed at the end of the current scope.
Moving it on the heap gets it out of that scope, but then it's your duty to delete it properly. Which you do by connecting the deleteLater slot to the finished signal.
-
@SGaist said in threads and created objects:
Object belonging and thread affinity are different things.
I need to pursue this a bit further. So, if I have an object (my worker object) that I move to another thread, is it true that anything created within that object prior to the move "belongs" to the original thread?
Specifically, my worker object has a member object m_serial. Presumably this object belongs to the original thread. After worker is moved, when this object creates something (like a QSerialPort), this "belongs" to the worker thread. When the worker thread does a write on it, I get the timer error. Is this because m_serial belongs to the original thread, but its QSerialPort belongs to the worker thread?
And if I have this right, is the solution that the worker thread would create its objects in start(), instead of having member objects?
-
@mzimmers said in threads and created objects:
I need to pursue this a bit further. So, if I have an object (my worker object) that I move to another thread, is it true that anything created within that object prior to the move "belongs" to the original thread?
If it's a QObject that is properly parented, it will move with it. Note that classes like QTcpSocket must be created in the new thread. You can however pass the descriptor like shown in the threaded QTcpSocket/Server example.
-
@SGaist said in threads and created objects:
If it's a QObject that is properly patented, it will move with it. Note that classes like QTcoSocket must be created in the new thread. You can however pass the descriptor like shown in the threaded QTcpSocket/Server example.
Actually a comment on that. Sockets that haven't been opened/bound can still be moved normally, however I agree it's a bad practice to depend on the actual implementation.
-
@SGaist said in threads and created objects:
If it's a QObject that is properly patented, it will move with it.
This is my current creation:
class Worker : public QObject { Q_OBJECT private: SerialPort m_serial; ... SerialPort::SerialPort(QObject *parent) : QObject (parent) { ...
Note that classes like QTcoSocket must be created in the new thread.
But not in the c'tor, correct? Because that is called prior to the thread move, so it would pertain to the original thread?
-
I fixed the typo of parented (damn autocorrect...)
Yes, m_serial will not be moved.
-
@SGaist said in threads and created objects:
I fixed the typo of parented (damn autocorrect...
Well, while you're at it..."QTcoSocket?"
-
If you want the
QObject
s to to be moved alongside with their parent to another thread, then you must pass them the parent. No parent, no way Qt to know whether the object's supposed to be moved. -
@mzimmers said in threads and created objects:
@SGaist said in threads and created objects:
I fixed the typo of parented (damn autocorrect...
Well, while you're at it..."QTcoSocket?"
Argle........ Done
-
@kshegunov I don't know how to do that in this case. If my SerialPort object is defined:
class SerialPort : public QObject { Q_OBJECT public: explicit SerialPort(Worker *parent = nullptr); ... SerialPort::SerialPort(Worker *parent) : QObject(parent)
Then how do I declare an instance of SerialPort in my worker object? If I do it like this:
SerialPort m_serial;
Then it doesn't seem to get moved.
-
The usual: pointer and allocate it in the constructor with a parent.
-
@SGaist OK, thanks. I had (incorrectly) inferred from kshegunov's post that it somehow could be done as an ordinary member variable.
-
@mzimmers No the inference is correct. This shall work, shan't it?
class Worker : public QObject { Q_OBJECT public: Worker(); private: SerialPort m_serial; }; Worker::Worker() : m_serial(this) { }
-
@kshegunov well...yes it does. I was missing the " : m_serial(this)" clause. Thanks!