I have a thread created by inheriting QThread in which I called exec() to initiate the event loop. And this class that inherits QThread has a method in it.
How can I call that method from the main thread for it to execute in the child thread?
I assume that the execution of that method has to be queued in the child thread's event loop, so calling threadObject->childThreadMethod() won't be a good idea.
Is there any solution to this?
You can not call every member functions of the thread, but only slots and Q_INVOKABLE methods.
Use QMetaObject::invokeMethod() to call such a method, and make sure to set the connection type to Qt::QueuedConnection.
That way, the method will be called in the second thread whenever the control returns to the event loop in the second thread. The caller, i.e. the main thread, will continue immediately, so you won't be able to get a return value from the called method.
Behind the scenes, QMetaObject::invokeMethod adds a MetaCallEvent to the second thread's event queue.
Alternatively, create a signal/slot connection, and then emit a signal whenever you want the slot to be called in the other thread.
to run some function in a separate thread you can use QtConcurrent::run (i use it with QFutureWatcher). To run it every 5 or so seconds, use QElapsedTimer class
QFuture<void> future = QtConcurrent::run(this, &MyClass::foo2, ...foo2 arguments);
http://qt-project.org/doc/qt-4.8/qtconcurrentrun.html#run or check it here https://stackoverflow.com/search?q=QtConcurrent%3A%3Arun
or you can subclass QThread, reimplement QThread::run() method with the stuff you want to happen in your thread, and then create an instance of your thread and call start() on it.
Related
I want to have the code executed by the OnTimer event to be executed in a separate (non-Main) background thread. this code does not access or communicate with the main thread/GUI. Simple question, I get the timer (TJvThreadTimer) is executed in it's own background thread, but:
Does the code contained in TJvThreadTimer.OnTimer event get executed in that background thread as well?
It is unclear from the limited documentation.
Thanks......
If you look at the timer's source code for yourself, you will see that the OnTimer event handler is called inside of a class method that is Synchronize()'ed by the internal background thread, which means the event handler runs in the main UI thread.
I am using CameraAPI2 of Android for app development.
I use the setOnImageAvailableListener(OnImageAvailableListener listener, Handler handler) to specify a callback or a listener.
The argument listener is a callback that will be run and the argument handler specifies the Thread the listener should be invoked on. If the handler is null, the listener should be invoked on the calling thread's looper.
The listener is an interface and its onImageAvailable() method should be overridden.
I am not quite clear what is the "calling thread". Is it the thread calling the setOnImageAvailableListener(...) method or the thread calling the onImageAvailable(...) method?
A calling thread is the thread that calls a method or the thread inside which a method is called. If thread1 calls method methodA (if methodA gets called from within thread1) then the calling thread of methodA is thread1. The listener argument specifies a callback method that will be called later in time. The calling thread will be the thread that calls the onImageAvailable method (the thread from which the call originated).
As per the official docs, the callbacks are delivered to the thread that makes the call to Camera.open.
I am working with CDialog in MFC.
In my dialog, I create a ui-thread:
CWinthread *threadCom = dynamic_cast<MyThreadClass*>(AfxBeginThread(RUNTIME_CLASS(MyThreadClass)));
Somewhere in my dialog class, I write:
threadCom->MyFunction();
My question is: "MyFuction()" is executed in main thread of dialog or ui-thread
Update after comment of AlexanderVX
For example, when user clicks on button on dialog
CMyDialog::OnBtnClicked() { threadCom->MyFunction(); }
"Calling a function" like calling a member function of a class is an action in your current thread.
If you want that Actions are executed asynchronously in the other thread you need some communication between the threads.
If the second thread has also a UI, it is possible to use messages (PostMessage) to inform the thread about an action. PostMessage is also a good way to inform the main thread about results from the worker thread.
If you need to transfer data too (more than a DWORD), you need a more complex data exchange that should be thread safe too.
I want to show a widget for displaying an animated loading gif while another function (pthread) computes a task.
I have tried to subclass my widget with a QThread class, and implemented the method run() where I call the method show(). However, my widget GUI froze.
How can I launch a widget where the GUI is processed separately?
You can't have widgets running on anything except the main thread.
Also, unless you're wanting to change how Qt handles threads, you should not be inheriting from QThread.
Instead, create a worker object that inherits from QObject and move that to the new thread. You can read how to really use QThread here.
Your worker object can then be moved to another thread, do its computation and communicate to the Gui widgets, on the main thread, via signals and slots.
For example, here's a brief outline of a worker class: -
class Worker : public QObject
{
Q_OBJECT
signals:
void finished();
void displayWidget();
private slots:
void run();
}
QThread pThread = new QThread;
Worker pObject = new Worker;
// move the pObject to the thread
pObject->moveToThread(pThread);
You can then control the thread with signals and slots.
// assuming you've added a run slot function to the Consumer class
connect(pThread, SIGNAL(started()), pObject, SLOT(run()));
connect(pObject, SIGNAL(finished()), pThread, SLOT(quit()));
connect(pObject, SIGNAL(finished()), pObject, SLOT(deleteLater()));
// Note the thread cleans itself up here, but if the app is quitting,
// waiting on the thread to finish may be required instead
connect(pThread, SIGNAL(finished()), pThread, SLOT(deleteLater()));
And start the thread: -
pThread->start();
Used this way, it also enables multiple objects to be moved to a single new thread, rather than creating a new thread per object instance.
So now, for example, if you wanted to display a widget at some point during the processing in the worker object, you'd emit its displayWidget() signal, having previously connected it to the Widget's show() slot.
QWidget* pWidget = new QWidget(parent); // assumes parent is initialized
// using Qt 5 connect call
connect(pWorker, &Worker::displayWidget, pWidget, &Widget::show);
You can't use QWidget (nor any derived classes) directly from threads other than the GUI thread. All you can do directly is to use a QImage owned by the worker thread and paint on it directly from that thread. Here, directly means that you are simply calling methods of objects.
What you need is a way to execute show() not directly in the invoking thread, but indirectly within the GUI thread's context. This is quite simple since QWidget::show() is a slot. Thus, from your computation thread, simply do:
QMetaObject::invokeMethod(widget, "show");
That's all. The implementation of invokeMethod will determine that widget lives in a different thread, and will automatically choose the QueuedConnection method of call delivery. Internally, it will post a QMetaCallEvent to widget. The widget's QObject::event method will act on the event and place the call to the show method. This will happen in the GUI thread.
You can use the same approach to set QProgressBar, for example:
int value = ...;
QMetaObject::invokeMethod(progressBar, "setValue", Q_ARG(int, value));
I have a form that is responsible for creating and setting up an instance of an object, and then telling the object to go do its work. The process is a long one, so there's an area on the form where status messages appears to let the user know something is happening. Messages are set with a setMessage(string msg) function. To allow the form to remain responsive to events, I create a new thread for the object to run in, and pass it the setMessage function as a delegate to allow the object to set status messages on the form. This part is working properly. The main form is responsive and messages posted to its setMessage function appear as expected.
Because the process is a long one, and is made up of many steps, I want to allow the user to terminate the process before it's finished. To do this I created a volatile bool called _stopRequested and a function called shouldStop() that returns its value. This is also given to the object as a delegate. The object can tell if it should terminate by checking shouldStop() periodically, and if it's true, shut down gracefully.
Lastly, Windows controls are not thread safe, so the compiler will complain if a thread other than the one that created the control tries to manipulate it. Therefore, the setMessage function is wrapped in an if statement that tests for this and invokes the function using the parent thread if it's being called from the worker thread (see http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx for a description).
The problem arises when the user requests a shutdown. The main form sets _stopRequested to true and then waits for the child thread to finish before closing the application. It does this by executing _child.Join(). Now the parent thread (the one running the form) is in a Join state and can't do anything. The child thread (running the long process) detects the stop flag and attempts to shut down, but before it does, it posts a status message by calling it's setMessage delegate. That delegate points back to the main form, which figures out that the thread setting the message (child) is different than the thread that created the control (parent) and invokes the function in the parent thread. The parent thread is, of course, in a Join state and won't set the text on the text box until the child thread terminates. The child thread won't terminate because it's waiting for the delegate it called to return. Instant deadlock.
I've found examples of signaling a thread to terminate, and I've found examples of child threads sending messages to the parent thread, but I can't find any examples of both things happening at the same time. Can someone give me some pointers on how to avoid this deadlock? Specifically, I'd like the form to wait until the child thread terminates before closing the application but remain able to do work while it waits.
Thanks in advance for the advice.
1-(lazy) Dispatch the method from a new Thread so it doesn't lock
2-(re-think) The main UI thread should be able to control the child thread, so forget the _stopRequested and shouldStop() and implement a childThread.Abort() , abort does not kill the thread, but sends a ThreadAbortException
which can be handled or even canceled
catch(ThreadAbortException e)
{
ReleaseResources();
}
Make the ReleaseResources safe by making various checks such as:
resource != null
or
resource.IsClosed()
The ReleaseResources should be called normally without abort and also by abort.
3-(if possible)stop the child, via main thread call ReleaseResources()
You may have to implement a mix of these.