Are the signal-slot execution in Qt parallelized? - multithreading

I have a basic Qt question on the way it handles Signals and Slots. I am very new to the framework, so pardon me if it sounds stupid. I was wondering if I have certain signals connected to certain slots.
signal1() ---> slot1(){ cout <<"a"; }
signal2() ---> slot2(){ cout <<"b"; }
signal3() ---> slot3(){ cout <<"c"; }
And in my code I call
emit signal1();
emit signal2();
emit signal3();
Does Qt guarantee to print out "abc" to the screen, in other words process the slots sequentially? Or will it spawn a separate thread to execute each slot?
Thanks!

By default:
1) If the signal is emitted in the thread which the receiving object has affinity then the slots connected to this signal are executed immediately, just like a normal function calls. Execution of the code following the emit statement will occur once all slots have returned.
2) Otherwise, the slot is invoked when control returns to the event loop of the receiver's thread. The code following the emit keyword will continue immediately, and the slots will be executed later in the receiver's thread.
More info about connection types here: http://qt-project.org/doc/qt-4.8/threads-qobject.html#signals-and-slots-across-threads

Just to add to Kotlomoy's correct answer :)
You can also control the type of connection from the default by supplying the optional parameter ConnectionType:
connect(obj, signal, obj, slot, connectionType)
Where your main options are:
Qt::QueuedConnection: This will only run when control returns to the event loop of the thread. I.e. will be added to the queue. specify this if you don't want your slot to be processed immediately which can be very useful.
Qt::DirectConnection: Alternatively you can specify direct connection (even between threads if you want), but generally you do not need or want to use this option since it is default when a signal is emitted to a slot within the same thread.
If you use QueuedConnection you grantee "abc" to be printed to the screen in that order.
Its worth noting if a directConnect event occurs while you are processing a previous slot (lets say some other external event triggers a signal like an IpSocket input) then you will get "interrupted". This won't happen in your simple example.

Related

PostThreadMessage: Create a message queue

I have an issue concerning a Thread lacking a message queue at the begin of its life cycle. MSDN explains
The thread to which the message is posted must have created a message queue, or else the call to PostThreadMessage fails. Use one of the following methods to handle this situation:
(1) Call PostThreadMessage. If it fails, call the Sleep function and call PostThreadMessage again. Repeat until PostThreadMessage succeeds.
(2) Create an event object, then create the thread. Use the WaitForSingleObject function to wait for the event to be set to the signaled state before calling PostThreadMessage. In the thread to which the message will be posted, call PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) to force the system to create the message queue. Set the event, to indicate that the thread is ready to receive posted messages.
Method (1) solves my issue, the second call to PostThreadMethod() always succeeds in my application.
However, I would like to comprehend the second method and simply don't understand "event object" (certainly not a normal Delphi event?) "to the signalled state" and "set the event to indicate".
QUESTION: Can someone please be so kind as to translate paragraph (2) into a short Delphi code example?
These event objects are synchronization objects, described in MSDN here: Event Objects.
At the bottom of that topic is a link to Using Event Objects which gives example code showing how to create events, set them, wait for them, etc.
In short you use the following functions:
CreateEvent to create the event objects.
CloseHandle to destroy it.
SetEvent and ResetEvent to set and reset the event object.
WaitForSingleObject to wait for it to be signaled.
You can use the TEvent class from the System.SyncObjs unit to wrap all of these low-level API calls. Then the process would become like so:
Create a TEvent object, Event say, in the reset state.
Create your worker thread, passing in Event.
Call Event.WaitFor in the manager thread to wait for the worker thread to signal that its message queue exists.
When the worker thread starts executing (i.e. at the start of its Execute method), have it create its message queue, and then set the event by calling Event.SetEvent.

NSURLSession dataTaskWithURL

I am using NSURLSession dataTaskWithURL:completionHandler. It looks like completionHandler is executed in a thread which is different than the thread(in my case, it's the main thread) which calls dataTaskWithURL. So my question is, since it is asynchronized, is it possible that the main thread exit, but the completionHandler thread is still running since the response has not come back, which is the case I am trying to avoid. If this could happen, how should I solve the problem? BTW, I am building this as a framework, not an application.Thanks.
In the first part of your question you seem un-sure that the completion handler is running on a different thread. To confirm this let's look at the NSURLSession Class Reference. If we look at the "Creating a Session" section we can see in the description for the following method the answer.
+ sessionWithConfiguration:delegate:delegateQueue:
Swift
init(configuration configuration: NSURLSessionConfiguration,
delegate delegate: NSURLSessionDelegate?,
delegateQueue queue: NSOperationQueue?)
Objective-C
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration
delegate:(id<NSURLSessionDelegate>)delegate
delegateQueue:(NSOperationQueue *)queue
In the parameters table for the NSOperationQueue queue parameter is the following quote.
An operation queue for scheduling the delegate calls and completion handlers. The queue need not be a serial queue. If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.
So we can see the default behavior is to provide a queue whether from the developer or as the default class behavior. Again we can see this in the comments for the method + sessionWithConfiguration:
Discussion
Calling this method is equivalent to calling
sessionWithConfiguration:delegate:delegateQueue: with a nil delegate
and queue.
If you would like a more information you should read Apple's Concurrency Programming Guide. This is also useful in understanding Apple's approach to threading in general.
So the completion handler from - dataTaskWithURL:completionHandler: is running on a different queue, with queues normally providing their own thread(s). This leads the main component of your question. Can the main thread exit, while the completion handler is still running?
The concise answer is no, but why?
To answer this answer this we again turn to Apple's documentation, to a document that everyone should read early in their app developer career!
The App Programming Guide
The Main Run Loop
An app’s main run loop processes all user-related events. The
UIApplication object sets up the main run loop at launch time and uses
it to process events and handle updates to view-based interfaces. As
the name suggests, the main run loop executes on the app’s main
thread. This behavior ensures that user-related events are processed
serially in the order in which they were received.
All of the user interact happens on the main thread - no main thread, no main run loop, no app! So the possible condition you question mentions should never exist!
Apple seems more concerned with you doing background work on the main thread. Checkout the section "Move Work off the Main Thread"...
Be sure to limit the type of work you do on the main thread of your
app. The main thread is where your app handles touch events and other
user input. To ensure that your app is always responsive to the user,
you should never use the main thread to perform long-running or
potentially unbounded tasks, such as tasks that access the network.
Instead, you should always move those tasks onto background threads.
The preferred way to do so is to use Grand Central Dispatch (GCD) or
NSOperation objects to perform tasks asynchronously.
I know this answer is long winded, but I felt the need to offer insight and detail in answering your question - "the why" is just as important and it was good review :)
NSURLSessionTasks always run in background by default that's why we have completion handler which can be used when we get response from Web service.
If you don't get any response explore your request URL and whether HTTPHeaderFields are set properly.
Paste your code so that we can help it
I just asked the same question. Then figured out the answer. The thread of the completion handler is setup in the init of the NSURLSession.
From the documentation:
init(configuration configuration: NSURLSessionConfiguration,
delegate delegate: NSURLSessionDelegate?,
delegateQueue queue: NSOperationQueue?)`
queue - A queue for scheduling the delegate calls and completion handlers. If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.*
My code that sets up for completion on main thread:
var session = NSURLSession(configuration: configuration, delegate:nil, delegateQueue:NSOperationQueue.mainQueue())
(Shown in Swift, Objective-C the same) Maybe post more code if this does not solve.

Is safe and good design AllocateHWND to respond more than one thread?

It's known that, in cases when one needs comunicate between UI thread and working thread, an hidden window must be created because of thread safety(handle reconstruction).
For exemplify:
Form1 has N dynamicaly created TProgressBar instances with the same name of a background running .
Is always garanteed that WM_REFRESH will only be called inside Task Thread.
Form1 has H : THandle property that allocates the following procedure:
procedure RefreshStat(var Message: TMessage); message WM_REFRESH;
Inside RefreshStat, in cases when there is only 1 background thread I could easily use L and W parameter to map Task Id and position.
I don't know if the title says what I want to know, but let's imagine if we have an application that has multiple background tasks running.
In my case I use TProgressBar to report progress the done.
Does AllocateHwnd garantee that all messages arrives with no race condition the hidden window?
What happens if two or more tasks post the message at the same time?
If this needs to be controled manually, I wonder if there is something else to do besides creating another message loop system in the custom message.
I hope the question is clear enough.
The message queue associated with a thread is a threadsafe queue. Both synchronous and asynchronous messages from multiple other thread are delivered safely no harmful date races. There is no need for any external synchronization when calling the Windows message API functions like SendMessage and PostMessage.
If two threads post or send messages to the same window at the same time, then there is no guarantee as to which message will be processed first. This is what is known as a benign race condition. If you want one message to be processed before the other then you must impose an ordering.

Qt - register multiple signals that when they've all emitted produce a giant signal connected to one slot

In my application I have the following situation:
an object emits signal removeCharacter
removeCharacter has a part A and B, and after part A is done it fires signal removePath
slot onRemovePath is connected to signal removePath and will remove the path for the character and then fire a signal pathRemoved
slot finishRemovingCharacter is connected to signal pathRemoved and will finish the rest of the character removal process
I don't want to always execute this finishRemovingCharacter logic when I fire the removePath signal
Is there some generic way to achieve the above, preferably something that Qt may already have available?
EDIT: I was hoping there would be a generic way to specify a sequence of signal and slot processing, instead of needing an intermediate slot to send a signal that it is done so the next step can execute.
As I see it, there are only two ways to handle with the situation.
Option 1:
Use two signals for the pathRemoved event. For example finishRemovingCharacter is connected to pathRemoved but NOT to pathRemovedSpecial.
Option 2:
Add proper arguments to the pathRemoved signal and then in the finishRemovingCharacter slot check if it should continue or just ignore this event in which case you'll just return;.

Worker thread doesn't have message loop (MFC, windows). Can we make it to receive messages?

Mfc provides both worker and UI thread. UI thread is enabled with message receiving capabilities (send, post). Could it be possible to let worker thread too receive messages.
Call CWinThread::PumpMessage() repeatedly until it returns a WM_QUIT message.
It seems you need a thread, that can handle multiple messages from another threads. Another threads would add-a-message to the message-queue of this thread. Well, in that case you may use PeekMessage to startup a loop, which would eventually create a hidden window, and then use GetMessage to get the messages. The other threads would use PostThreadMessage with the thread ID (the one having Peek/GetMessage), and the message-code, LPARAM, WPARAM.
It would be like (not syntactically correct):
TheProcessor()
{
MSG msg;
PeekMessage(&msg,...);
while(GetMessage(&msg...)
{ /* switch case here */ }
}
The threads would call PostThreadMessage - See MSDN for more info.
When you need to send more data than LPARAM/WPARAM can hold, you eventually need to allocate them on heap, and then delete AFTER processing the message in your custom message-loop. This would be cumbersome and buggy.
But... I would suggest you to have your own class, on top of std::queue/deque or other DS, where you can add AddMessage/PushMessage, and PopMessage (or whatever names you like). You need to use SetEvent, WaitForSingleObject to trigger the new message in loop (See one of the implementation here. You may make it generic for one data-type, or make it template class - that would support any data-type (your underlying DS (queue) would utilize the same data-type). You also need not to worry about heaps and deletions. This is less error prone. You may however, have to handle MT issues.
Using Windows events involves kernel mode transition (since events are named/kernel objects), and you may like to use Conditional Variables which are user objects.Or you may straightaway use unbounded_buffer class from Concurrency Runtime Library available in VC10. See this article (jump to unbounded_buffer).
Yes you can create a message queue on a worker thread. You will need to run a message pump on that thread.

Resources