MultiThreading - Sharing objects between threads without using events?
I'm writing a console application that uses Qt multithreading.
I need to create complex objects with multiple compositions, and then use these objects both in the main thread and in worker threads (for example I need to close a network connection from within a worker thread, and also be able to shut it down from the main thread).
I have read about thread affinity, parent/child relationship, and object reentrancy which seem to add a lot of constraints.
Since I'm porting my application from Java, and since I am very unfamiliar with the event driven programming, is there any way to share objects between threads without using events, event loop or the signal and slots mechanism?
Any suggestion or advice would be much appreciated.
If you protect the data with e.g. [[Doc:QMutex]], you can call code in another thread directly. See the linked docs for a basic example.
And don't forget to read "Threads, Events and QObjects":http://developer.qt.nokia.com/wiki/Threads_Events_QObjects, if you didn't already.
If you are not using UI components, all objects are at first classes and classes can be used from any thread. If you are using signal/slot, thread affinitxy comes into the game, if you don't it does not :-)
calling methods on objects from different threads is always a tricky thing, if the objects are not 100% thread save. Think of 2 threads calling erase(iterator) on an object at the same time. You never know which thread is processed first and the other iterator might become invalid...
So if you use the same classes (QString, QVector, whatever) from different threads, you must ensure, that access is done in a thread save way, as the objects are (AFAIK) not thread save. reentrant means, you can call them from more then one thread, but not at the same time!
Ok well that sounds good, I'll make sure to protect my data with mutexes to ensure my code is thread safe.
There is an issue I'm still encountering though: I need to use sockets in different threads, but that doesn't seem to work. The documentation ("QTcpServer::nextPendingConnection":http://doc.qt.nokia.com/latest/qtcpserver.html#nextPendingConnection) states:
bq. Note: The returned QTcpSocket object cannot be used from another thread. If you want to use an incoming connection from another thread, you need to override incomingConnection().
Is overriding incomingConnection() the only way to do so? Or are there any alternatives?
First of all, QTcpSocket, being a QObject, is not thread safe at all but only reentrant. And since it's event based, you must be 100% sure that no event dispatching is going on inside the thread the QTcpObject is living in, if you try to access it from other threads.
Second, I've found that that piece of documentation is actually wrong, cf. my docnote on http://developer.qt.nokia.com/doc/qt-4.7/qtcpserver.html .
Oh good to know that :)
How can I use moveToThread() with QtConcurrent?
Also, is it good practice to create the QTcpSocket with nextPendingConnection() in the new thread? Or is moveToThread a better option?