Query related to threads in Qt - multithreading

I want my application to wait indefinitely until a task gets completed in another thread.
How do I perform this in Qt?
On windows, we use waitforsingletonobject, but is there any alternative to this?

Waiting for threads to finish certain tasks (thread synchronization) is the job of the QWaitCondition class.

Call wait on your QThread object.

Use QtConcurrent::run. See my answer to this question. Note that the QFutureWatcher API can work in blocking (the waitForFinished method) and non-blocking (the finished signal) modes.

Related

Mechanism of join() in multithreading

I was studying about multi-threading and came across join().
As I understand right, using join() on the thread makes process wait until 'joined' thread terminates. For example, calling t1.join() in main will make main wait until the job in thread t1 is finished and t1 terminates.
I'm just curious that how the function join() make this possible - how does it make current thread 'blocked' inside the function? Does join() force execution of joined thread first so any other thread should wait until that thread terminates? Or, is there some way to communicate between two threads(the thread who called join() and the thread who is joined)?
I will be waiting for the answer. Thanks a lot!
To be able to join you need to be able to wait on some event. Then join looks like this:
function join(t : Thread)
// do this atomically
if already done
return
wait on termination event of t
end
Waiting can be done in one of two ways:
Looping and periodically checking if the event has happened (busy wait)
Letting the system reclaim the resources of the thread and be woken up on a system event, in that case waking the thread is managed by the scheduler of the OS
It's rather language specific.
Once you create a thread, it starts running.
A join operation is when your main process stops and waits for the thread to exit and capture a return code. It will block until your thread completes - that's rather the point, as it allows for a synchronization to occur - everything in your program is at a 'known state'.
Related is the detach operation, which is effectively saying 'I don't care any more'.

set a deadline for each callback in an event-driven/ event-loop based program

In a typical ASIO or event-based programming library like libevent, is there a way to set a deadline for each callback?
I am worried about possible infinite loops within the callbacks. Is there a way to gracefully detect them, remove the misbehaving callback from task queue and continue processing other tasks in the queue?
I can think of a way to detect it through an external thread and kill the event-loop thread and create a different thread but I am trying to see if there are any other commonly used methods. I believe this is a problem which someone has faced at some point of time and thought through a solution
There is no general way to unstick a thread without its cooperation, whether it's running a callback or not. The thread may hold critical locks or may have acquired resources that would never get released if the thread was somehow coerced to stop from the outside.
If you really do need this functionality, then all code that could potentially be interrupted must be designed to support some specific method of interruption. You can start a deadline timer when you enter the callback and cancel it when you're finished. The deadline timer would have to trigger the thread's interruption mechanism. You'd need at least one other thread running the I/O service in order for some thread to run the timer handler while the callback was running in another thread.
You can also isolate the code in its own process with some kind of wrapper. Then if the code fails to terminate, you can kill the process from the outside.

How to make Qt work when main thread is busy?

Main (function main is there) thread of my program is reserved for non-GUI tasks. It calls a number of lengthy calculation functions. All implemented GUI's have been doing their work in a separate threads.
I'm now going to implement one more GUI using Qt. Qt documentation says all GUI related tasks should be done in main thread.
In my case, inserting occasional QCoreApplication::processEvents() calls in main thread would be virtually useless due to great delays between them.
Is there any way to overcome this constraint of Qt?
Is it impossible to do something non-GUI related in main thread of Qt program?
No, you should be doing your calculations in a separate thread. As you already mentioned, there is a work-around available in QCoreApplication::processEvents(), but it sounds like you're unable to make that work for you.
If you don't want to have to do all the work of setting up a QThread and moving all your code, you may find that the QtConcurrent::run function is useful - it allows you to run a function asynchronously.
A few pointers: You should try and keep your main (GUI) thread as light as possible. Large amounts of IO or calculations should either be done asynchronously using QtConcurrent::run, or run inside a separate QThread. Depending on the complexity of your code, you may be able to get away with the QtConcurrent method.
It's best to offload the long computations onto other threads so the main GUI thread remains responsive. The old-school uniprocessing way of doing things would be be to make sure your computations never run for too long without polling GUI event handler, but that doesn't scale to multi-cores.
Fortunately Qt has excellent threading support. In the past you'd have to roll-you-own system for e.g farming out tasks to a thread-pool using QThread, QMutex, QWaitCondition etc, but recent Qt releases have made things easier with higher level abstractions like QThreadPool, QtConcurrent::run and QFuture.
I don't know how things will go if you call QApplication::exec() from another thread, which then becomes your gui thread. Just an idea.
(Let us know if it works, it'd be interesting...)
The concept of main thread is not clearly defined in Qt documentation. Actually, the main thread of a process (process that executes the Process.run function) can be different from the main Qt thread (thread that instantiates the first Qt object like a QApplication), although both "main" threads are often the same one.
Example of valid code structure:
function below will run in the process' non-main thread 'thread-1', that will become immediately Qt's main thread.
def startThread1():
app = QApplication(sys.argv)
app.exec_() # enter event loop
code below run in process' main thread, not to be confused with the main Qt and unique GUI thread of the process.
thread1 = Thread(target=self.startThread1)
thread1.start()
input('I am busy until you press enter')

ThreadPool, QueueUserWorkItem and Deadlock on Shutdown

I just implemented a thread pool like described here
Allen Bauer on thread pools
Very simple implementation, works fine, but my application no longer shuts down. Seems that two worker threads (and one other thread, I guess the queuing thread) stuck in the function
ntdll.ZwRemoveIoCompletion
I remember to have read something about IO completions in the help entry for QueueUserWorkItem (the WinAPI function used in the thread pool implementation), but I couldn't understand it properly. I used WT_EXECUTELONGFUNCTION for my worker threads since execution can take a while and I want a new worker thread created instead of waiting for the existing ones to finish. Some of the tasks assigned to the worker threads perform some I/O stuff. I tried to use WT_EXECUTEINIOTHREAD but it does not seem to help.
I should mention that the main thread waits for entry to a critical section witht the call stack being
System.Halt0, System.FinalizeUnits, Classes.Finalization, TThread.Destroy,
RtlEnterCriticalSection, RtlpWaitForCriticalSection
Any ideas what I'm doing wrong here? Thanks for your help in advance.
To make sure the worker threads shut down, you need to have some way of waking them up if they are waiting on the empty IO completion port. The simplest way would seem to be to post a NULL message of some kind to the port - they should then treat this as a signal to halt in an orderly fashion.
You must leave from the critical section before you can enter again. So the problem is inside a lock.
In some thread:
EnterCriticalSection(SomeCriticalSection);
sort code...
LeaveCriticalSection(SomeCriticalSection);
In some other thread:
EnterCriticalSection(SomeCriticalSection);
clean up code...
LeaveCriticalSection(SomeCriticalSection);
If the sort code is running in the first thread and the second thread try to run the clean up code the second thread will wait until the sort code finish and you leave the critical section. Only after leaving the critical section you can enter the same critical section. I hope this will help you narrow down the deadlock code because it is inside a critical section.
To get the completion port handle you can save it's handle when you create the completion port:
FIoCPHandle := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0 , 0, FNumberOfConcurrentThreads);
When using QueueUserWorkItem, as long as the worker threads have been returned to the thread pool, you should not have to do anything to shut them down. The WT_EXECUTEDEFAULT component of the thread pool queues the work items up onto an I/O completion port. This port is part of the thread pool's internal implementation and is not accessible to you.
Could you provide some more detailed call stacks for the threads that appear to be stuck? It would make this problem much easier to diagnose.

Is SetEvent atomic?

Is it safe to have 2 or more threads call the Win32 API's SetEvent on the same event handler not being protected by a critical section?
It's safe, but remember that if one thread Sets it, and another thread Sets it at the same time, you're not going to get two notifications, just one; since the 2nd one changed it from True to...True. If you're worried about this, use Semaphores instead.
Assuming you have multiple threads waiting on the same event, running the same code.
If your code doesnt clear the event until its done processing, you effectively have a CS. Since the event remains signaled until it is cleared(aka not autoreset), having multiple threads signal the does nothing except spin the CPU.
If your code clears it at the begining of processing or the event is autorset, then you would have multiple threads running the same function, which is unsafe if these threads share anything.
there are no restrictions on calling SetEvent from multiple threads.

Resources