I have a Qt application that has two threads: the main thread that handles the GUI and a second thread that manages network connections. Here is the thread code:
void thread::run()
{
QTcpServer server;
server.connect(&server,SIGNAL(newConnection()),this,SLOT(OnConnect()));
//...
}
When I put a breakpoint at the start of OnConnect() and debug the application, it announces that OnConnect() is being called from the main thread!
How can I have OnConnect() run in the same thread as the QTcpServer?
To give a more thorough answer, look a little deeper into how signal-slot connections and thread contexts interact. Basically, for more connections (auto-connect), the slot will be directly called if both the emitter and the receiver are in the same thread context, otherwise it will be a queued connection, and the slot will be run in the thread context of the object that contains the slot. In this case, it must be queued, which implies that your thread is part of the main application's thread context, not its own. This is reinforced by the documentation Qt provides for an overview of its threading, where it states that the QThread instance is "owned" by the thread context that created it, not the thread context that it represents. This means you have three main choices:
You can use moveToThread() to move the thread into its own context. Note that this may cause problems when deleting the thread unless you move it back to the context where it will be destroyed, and this can only be done in the source-thread context, so it would have to be done before the run function exited.
You can treat the QThread instance as a handle to the thread, not as being part of the thread itself. If you need things done in the context of the new thread, create a different object to handle those, and instantiate them in the context of the new thread (inside the run function). This is what I would recommend.
Force a direct connection. This means you would need to ensure the code running in the slot is thread-safe, ignoring Qt's built-in methods of making those functions thread-safe. This is what you have done.
It seems like the problem was that I wasn't passing Qt::DirectConnection as the last parameter of connect().
After adding that, it worked.
Related
when creating a thread we pass an entry point method/function , why should I have this method , what is the purpose of it?
OS needs to know where a new thread of execution starts. When using a high-level programming language, one does not specify an address of machine instructions in memory to be executed in the context of a new thread, but uses execution units defined in the language like functions or methods. If thread creation worked like fork and execution of a new thread started at the point of fork invocation, then both threads would have the same local variables that usually reside in stack. Even if there is a copy of the stack created for a new thread, both threads will run the same clean-up code when leaving scopes (e.g., in C++ a smart pointer will be freed twice). So when you specify a starting point for a new thread, you are sure it will allocate a stack-frame of its own and function's epilog won't be executed twice.
A thread has to start somewhere. The pthread interface requires you to provide a function of the form
void *start_thread( void *arg );
void * is used because they can refer to anything.
When a thread is created, the function to provide is called as the thread's starting point. Think of it like main() for the thread, but with different argument and return types.
I am confused on one point with notify method. "notify() : It wakes up one single thread that called wait() on the same object." So lets say two thread called wait for the same object. So when I call notify which thread will be notified?
You can't know which one will be notified. Spec says:
public final void notify()
Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation.
I have a TListView in the main Form (Thread) and many other threads that add/delete item from the list using Synchronize method. But the main thread has also a method that modify the list items and I want that method not to be interrupted by other threads that wants to execute code in the main thread. Is this possible ?
Do you have evidence that what you are worried about is happening? You shouldn't, because it can't happen. That is what Synchronize is for. Methods executing in the main thread must complete before the main thread can service the message queue to process work items dispatched via Synchronize from worker threads so you have nothing to worry about.
When a worker thread uses Synchronize it essentially just posts a message to the main thread telling it that it has work for it to do. If the main thread is busy executing another method then the worker thread will simply block until the main thread is finished, subsequently processes the message queue, picks up the work item, executes it, and then posts back to the worker thread that the work is complete (leaving the worker thread free to then continue).
This, of course, assuming that the method in your main thread is not calling Application.ProcessMessages() or CheckSynchronize() (or you are using a tricky component that does this, or something similar, without you knowing it -> see : Delphi 7, Windows 7, event handler, re-entrent code)
I'm newbie to Qt. I haven't found an answer in a reasonable time and decided to ask here.
I have a thread, let's call it Thread1 with Qt object which have a connected slot. Signal is emitted from the same thread (Thread1).
And I'm disconnecting this slot from another Thread2.
Is this operation thread safe?
Are there any problems, if a signal is emitted and slot is disconnected exactly at the same time?
Just looking at the docs, it looks safe to me:
http://qt-project.org/doc/qt-4.8/qobject.html
Note: All functions in this class are reentrant, but connect(), connect(), disconnect(), and disconnect() are also thread-safe.
http://qt-project.org/doc/qt-4.8/qobject.html#disconnect
Note: This function is thread-safe.
Also make sure that you are using Queued Connections when you are connecting the signal of one thread to the slot of another. The Auto-connect may misbehave (and do direct connection) if both objects happen to be in the same thread during the time of the connection.
Hope that helps.
EDIT: More about Thread Safety:
http://qt-project.org/doc/qt-4.8/threads-reentrancy.html
http://qt-project.org/doc/qt-4.8/threads-qobject.html
I have made a Gui thread and a QTcpSocket thread in Qt.I want to access data
from QTcpSocket thread to Gui thread.How to solve it?
Do i need to declare some global variable and how?
The easiest way is to communicate via signal-slot connections. There is one QObject in each thread. The sending object has a signal, which is connected to the slot of the receiving object in the other thread.
In this setup, you make sure that the objects on both ends of the connections are configured to live in the correct threads. You might need to call QObject::moveToThread(). QObject also has a property where you can get the current thread (for debugging purposes in this case).
Then just establish the signal-slot connection as usual. Since both objects are in different threads, when the signal is triggered, a slot invocation event will be placed in the event loop of the receiving flag. This is explained in the Qt documentation, look for Qt::QueuedConnection.
The QTcpSocket is created from the gui thread.
So at that point the gui thread has a pointer to the socket object.
It then creates a connection between a slot in the gui and a signal in the socket.
In the socket object whenever you get data you simply emit a signal containing the data, which will be picked up by the gui thread.
You can pass any Qt type eg QString, QByteArray (or a raw pointer), through a signal/slot very efficiently. The details if signals between threads are also handled automatically.