[Interest] Passing constructor arguments to an object that is to be run on a separate thread
d3fault
d3faultdotxbe at gmail.com
Fri Nov 9 12:36:36 CET 2012
I'm working on a revision to ObjectOnThreadHelper (see:
http://lists.qt-project.org/pipermail/interest/2012-October/004547.html
), and want to add the ability to send in arguments to the constructor
of the object that is to be run on the separate thread. Another thing
I want to add is being able to pass in multiple object types, but that
is lower priority and easier to accomplish. If I can get it in good
enough shape I want to contribute it and hopefully see all future Qt
threading using it.
Basically I'm noticing that you have to choose between one of the two
following (is there a 3rd?????):
1) With QObject::moveToThread, your constructor for the object you
wish to run on the other thread, which includes all parent
constructors, is NOT run on the designated thread. This breaks
'threads should manage their own resources'
2) With QThread::run, your constructor args have to be saved during
instantiation of the QThread derivative, then passed into the object
you wish to run on a separate thread when it is instantied in
QThread::run()
Which of these two options... sucks less?
Or, what do YOU do to pass in constructor arguments to an object you
are running on a separate thread?
Here is some sample code that explains the two in further detail. If
you get it, stop reading here (any solutions/suggestions? Is
saving/passing the constructor args the preferred way and good enough
(it just seems hacky)?) :
===moveToThread===
//major pitfall: threads do not manage their own resources
consider the following classes:
class MyObject : public QObject
{
Q_OBJECT
public:
MyObject(QObject *parent = 0);
private:
AnotherObject *m_ChildQObject1;
}
//in cpp file
MyObject::MyObject(QObject *parent) : QObject(parent)
{
m_ChildQObject1 = new AnotherObject(this); //properly set up
parent/child relationship. AnotherObject will change thread affinity
on .moveToThread().
}
class AnotherObject : public QObject
{
Q_OBJECT
public:
AnotherObject(QObject *parent = 0);
private:
YetAnotherObject *m_AQObject2;
}
//in cpp file
AnotherObject::AnotherObject(QObject *parent) : QObject(parent)
{
m_AQObject2 = new YetAnotherObject(); //this member of AnotherObject
(of which we might not be able to easily modify) does not have 'this'
passed into it's constructor, so it is not a formal child and does not
get moved to thread!!!!!!!
}
...and then if we do....
MyObject *object = new MyObject();
object->moveToThread(someThread);
//results in:
//object = on someThread
//MyObject::m_ChildQObject1 = on someThread
//YetAnotherObject::m_AQObject2 = NOT on someThread (it's still on
whatever thread 'new MyQObject()' line above was run on). The thread
does not manage its own resources :(
===QThread::run()===
//major pitfall: no easy glue-free way to pass constructor arguments
You need:
class YourObjectThread : public QThread
{
Q_OBJECT
public:
YourObjectThread(QObject *parent = 0, int customArg1, double customArg2); //etc
private:
int m_ArgHolder1;
double m_ArgHolder2;
//etc
protected:
virtual void run();
}
//in cpp file
YourObjectThread::YourObjectThread(QObject *parent, int customArg1,
double customArg2) : QThread(parent)
{
//save the args
m_ArgHolder1 = customArg1;
m_ArgHolder2 = customArg2;
}
void YourObjectThread::run()
{
//pass them in
YourObject *obj = new YourObject(m_ArgHolder1, m_ArgHolder2);
exec();
delete obj;
}
d3fault
More information about the Interest
mailing list