[SOLVED] Access QObject subclass across threads
-
Hello everybody,
It's been said really much about threads and QObjects and thier proper use but I still can't understand why I get a crash on the following scenario:
I have a QObject custom subclass:
@class CustomObject : public QObject
{
Q_OBJECT
public:
void changeMyData(someDataType newValue)
{
myData = newValue;
}public slots:
void slot_changeMyAnotherData(someDataType newValue)
{
myAnotherData = newValue;
}private:
someDataType myData;
someDataType myAnotherData;
};@And I have two threads both accessing the same CustomObject instance: main thread calls slot_changeMyAnotherData and another thread calls changeMyData; the point is that they never access the same variables but this still produces a crash, why is that ? I cant get it... Could someone clarify this, please?
Thanks in advance! -
Hi,
Without some more code it's difficult to help.
Technically your class looks ok but how do you access it ? Are you sure you don't have uninitialized pointers ? etc...
EDIT:incomplete answer
-
[quote author="SGaist" date="1375105096"]Hi,
Without some more code it's difficult to help.
Technically your class looks ok but how do you access it ? Are you sure you don't have uninitialized pointers ? etc...[/quote]
Hi,
Thanks for the quick answer! From your words I understand that there's no mystical stuff going on with QObjects when accessing across threads and there should be no problems accessing different data fields of the same QObject simultaniously ?"The official documentation seems unclear to me :":http://harmattan-dev.nokia.com/docs/library/html/qt4/threads-qobject.html
bq. If you are calling a function on an QObject subclass that doesn't live in the current thread and the object might receive events, you must protect all access to your QObject subclass's internal data with a mutex; otherwise, you may experience crashes or other undesired behavior.
Sounds like all the data access must be synchronyzed even not overlapping...
-
Sorry I've hit the reply button to soon...
What I was about to write was:
Writing to a QObject is the same a writing to any other class (meaning that proper locking must be done or that you have a proper lock free implementation).
What the doc says is that a QObject has an additional rule, you have to take in account that the QObject might receive events any time (i.e. signal/slots interaction between objects living in different threads), so you might be writing to your field by calling your slot like a normal function and there might be an object in another thread that might emit the signal to modify the same variable.
Hope I didn't set you on the wrong path
-
[quote author="SGaist" date="1375111273"]
What the doc says is that a QObject has an additional rule, you have to take in account that the QObject might receive events any time (i.e. signal/slots interaction between objects living in different threads), so you might be writing to your field by calling your slot like a normal function and there might be an object in another thread that might emit the signal to modify the same variable. [/quote]
That's exactly what I wanted to know, thanks!And You actually set me on the right path because after reading your comment I concentrated on some other aspects of my code rather than multithreading or QObjects and found the problem... I was reinterpret casting some multiple inherited subclass pointer to quin32 and then casting it back to the second base class pointer istead of casting it to subclass pointer first and then to the base class pointer :)
Thanks a lot ! :) -
You're welcome !
So much casting makes me wonder, are you sure you're not preparing a can of worm ?
-
In general, using reinterpret_cast on data structures is a bad idea -- it makes it really hard to debug your program. I only use it to interpret byte streams.
If you simply must cast, use qobject_cast for safety (or dynamic_cast for non-QObjects).