PDA

View Full Version : QThread communicate threadsafe



Ini
1st June 2016, 21:59
I know it's not threadsafe to call a function of another thread in Mainthread. Is it allowed to call a signal form another thread without any problems? Lets say this code is in MainWindow:


MainWindow.cpp
thread->moveTOThread(obj);
emit obj->Signal();

or is this the way to go:

Obj.h
signals:
void testSignal();
public slots:
void Func();

MainWindow.h
void testSignal();

MainWindow.cpp
thread->moveTOThread(obj);
connect(this,SIGNAL(testSignal()),obj,SIGNAL(testS ignal()));
emit testSignal();

Obj.cpp
connect(this,SIGNAL(testSignal()),this,SLOT(Func() ));

thank you

anda_skoa
2nd June 2016, 08:46
I know it's not threadsafe to call a function of another thread in Mainthread. Is it allowed to call a signal form another thread without any problems? Lets say this code is in MainWindow:


MainWindow.cpp
thread->moveTOThread(obj);
emit obj->Signal();

Sending another object's signal is generally a bad idea, better consider signals to have the same access restrictions as protected methods.

In any case, this just emits the signal in the context of the main thread.



or is this the way to go:

Obj.h
signals:
void testSignal();
public slots:
void Func();

MainWindow.h
void testSignal();

MainWindow.cpp
thread->moveTOThread(obj);
connect(this,SIGNAL(testSignal()),obj,SIGNAL(testS ignal()));
emit testSignal();

Obj.cpp
connect(this,SIGNAL(testSignal()),this,SLOT(Func() ));


Why not just connect to the slot directly instead of first connecting to a signal and then connecting that signal to a slot?

Cheers,
_

Ini
2nd June 2016, 14:25
obj is an array in my code i just simplified it here. Then i would need an array of signals right? When I only want to adress one part of the array eg obj[2], when I emit the signal.

If that works with the array of signals i had a thinking error.

anda_skoa
2nd June 2016, 17:33
There is no such thing as an array of signals.

Maybe you could describe what you are currently trying to solve?

Cheers,
_

Ini
2nd June 2016, 17:56
mainwindow.cpp

Obj obj[maxObjectCount];
Obj thread[maxObjectCount];
for (int i = 0; i < maxObjectCount; i++) {
obj[i].moveToThread(thread[i])
}

Now i need to call a Function of lets say obj[10] in mainwindow.cpp

Idk know at all how to do that. Nobody can exlain threads that sb understand it seems, maybe nobody understands them I'm thinking ^^

anda_skoa
2nd June 2016, 22:28
So you need to call a method in an object and you are asking how to emit a signal?



obj[10].someMethod();


Cheers,
_

Ini
2nd June 2016, 22:30
this is not threadsafe

wysota
3rd June 2016, 08:18
If someMethod() is a slot you can do this:


QMetaObejct::invokeMethod(&obj[10], "someMethod", Qt::QueuedConnection);

anda_skoa
3rd June 2016, 08:49
this is not threadsafe

You mean because obj[10] could have been deleted by its thread?

Because that is the only inherently unsafe part in that call.


If someMethod() is a slot you can do this:


QMetaObejct::invokeMethod(&obj[10], "someMethod", Qt::QueuedConnection);

That of course also accesses "obj" without any guard, so it has the same problem as the direct method call.
The only difference is that "someMethod" will be executed by the object's owner thread, which also has to run an event loop to be able to do that.

Cheers,
_

Ini
3rd June 2016, 12:39
You mean because obj[10] could have been deleted by its thread?

Because that is the only inherently unsafe part in that call.



That of course also accesses "obj" without any guard, so it has the same problem as the direct method call.
The only difference is that "someMethod" will be executed by the object's owner thread, which also has to run an event loop to be able to do that.

Cheers,
_

thx for explaing. First I want to say that I dont't want to use invokeMethod cause there is not compile-time errors if i write the functionname wrong. Just want to point that out, you must not comment that :)

Then i have two questions. Why always people say use Signals&Slots when it seems there is like no advantage in that, when the only possilbility that the call is unsafe is that the obj gets deleted? Is it cause you have then Connectiontypes available?

This leads my to my second question. What connectiontype would be equal to obj[10].someMethod(); ?

anda_skoa
3rd June 2016, 16:14
thx for explaing. First I want to say that I dont't want to use invokeMethod cause there is not compile-time errors if i write the functionname wrong. Just want to point that out, you must not comment that :)

Well, you don't have that with the SIGNAL/SLOT macros either.



Why always people say use Signals&Slots when it seems there is like no advantage in that, when the only possilbility that the call is unsafe is that the obj gets deleted?

Using signal/slot or invokeMethod makes it easy to cross thread boundaries, make the target thread execute a method.
Especially nice when communicating from a worker thread to the main thread.



What connectiontype would be equal to obj[10].someMethod(); ?
Qt::DirectConnection

Cheers,
_

Ini
3rd June 2016, 16:16
"Well, you don't have that with the SIGNAL/SLOT macros either."

I will get an compile error if the Slot does not exist that i type in with connect. With invokemethod i do not get an compile-error.

anda_skoa
4th June 2016, 10:48
I will get an compile error if the Slot does not exist that i type in with connect.
No, not with the SIGNAL and SLOT macros.

That type of connect does runtime checking, not compile time checking.
SIGNAL and SLOT convert their argument into a string, very similar to what you do manually when using invokeMethod.

Cheers,
_