Why are threads created with message queues? - windows

This is windows specific question.
According to microsoft docs,
The system maintains a single system message queue and one thread-specific message queue for each GUI thread. To avoid the overhead of creating a message queue for non–GUI threads, all threads are created initially without a message queue. The system creates a thread-specific message queue only when the thread makes its first call to one of the specific user functions; no GUI function calls result in the creation of a message queue.
So far I believed on that all threads are created initially without a message queue. Today, I tested this with PostThreadMessageW because it is stated that
The function fails if the specified thread does not have a message queue.
However, PostThreadMessageW always returns 1 (TRUE) for all threads right after creation.
DWORD dwThreadID = GetCurrentThreadId();
BOOL bResult = PostThreadMessageW(dwThreadID, WM_QUIT, 123, 456);
Why is this happening?

Related

When should I use a wait function like MsgWaitForMultipleObjects, and when shouldn't I?

So I am trying to understand the message processing code of Unreal Engine on Windows OS, and I didn't find any frequent usage of the function MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx in the message pumping code.
The engine message pumping goes like this:
MSG Message;
// standard Windows message handling
while(PeekMessage(&Message, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Message);
DispatchMessage(&Message);
}
For context, this code will run every frame one to three times, meaning the code will be executed each 2 - 5 milliseconds on average throughout the running time of the application. A) Does that make wait functions unnecessary? or am I missing something here!
B) Is there any rough estimation of how long an application could be busy doing 'other stuff' before processing incoming messages? For instance if an application only processes messages every 50 millisecond, is that a bad practice? or is that a reasonable way of doing it? And what if the period became 500 milliseconds and so?
Use MsgWaitForMultipleObjects/etc if you need to both handle window message processing and kernel handle or alertable waits in a single thread. If you are only doing message processing then simply use a normal GetMessage based message loop, if only doing kernel handle or alertable waits then use WaitForMultipleObjects as appropriate.

How to use multiple sessions per connection in a multi-threaded application?

Suppose I have one connection c and many session objects s1, s2 .. sn, each working in different threads t1, t2 ... tn.
c
|
-------------------------------------------------
| | | |
(t1,s1) (t2,s2) (t3,s3) ...... (tn,sn)
Now suppose one of the thread t3 wants to send a message to a particular queue q3 and then listen to the reply asynchronously. So it does the following:
1: c.stop();
2: auto producer = s3.createProducer(s3.createQueue(q3));
3: auto text = s3.createTextMessage(message);
4: auto replyQueue = s3.createTemporaryQueue();
5: text.setJMSReplyTo(replyQueue);
6: producer.send(text);
7: auto consumer = s3.createConsumer(replyQueue);
8: consumer.setMessageListener(myListener);
9: c.start();
The reason why I called c.stop() in the beginning and then c.start() in the end, because I'm not sure if any of the other threads has called start on the connection (making all the sessions asynchronous — is that right?) and as per the documentation:
"If synchronous calls, such as creation of a consumer or producer, must be made on an asynchronous session, the Connection.Stop must be called. A session can be resumed by calling the Connection.Start method to start delivery of messages."
So calling stop in the beginning of the steps and then start in the end seems reasonable and thus the code seems correct (at least to me). However, when I thought about it more, I think the code is buggy, as it doesn't make sure no other threads call start before t3 finishes all the steps.
So my questions are:
Do I need to use mutex to ensure it? Or the XMS handles it automatically (which means my reasoning is wrong)?
How to design my application so that I dont have to call stop and start everytime I want to send a messages and listen reply asynchronously?
As per the quoted text above, I cannot call createProducer() and createConsumer() if the connection is in asynchronous mode. What are other methods I cannot call? The documentation doesn't categorise the methods in this way:
Also, the documentation doesn't say clearly what makes a session asynchronous. It says this:
"A session is not made asynchronous by assigning a message listener to a consumer. A session becomes asynchronous only when the Connection.Start method is called."
I see two problems here:
Calling c.start() makes all sessions asynchronous, not just one.
If I call c.start() but doesn't assign any message listener to a consumer, are the session(s) still asynchronous?
It seems I've lots of questions, so it'd be great if anyone could provide me with links to the parts or sections of the documentation which explains XMS objects with such minute details.
This says,
"According to the specification, calling stop(), close() on a Connection, setMessageListener() on a Session etc. must wait till all message processing finishes, that is till all onMessage() calls which have already been entered exit. So if anyone attempts to do that operation inside onMessage() there will be a deadlock by design."
But I'm not sure if that information is authentic, as I didn't find this info on IBM documentation.
I prefer the KIS rule. Why don't you use 1 connection per thread? Hence, the code would not have to worry about conflicts between threads.

MPI - Use multiple threads to listen for incoming messages

I am working on a project that uses MPI routines and multiple threads for sending and receiving messages. I would like each receiving thread to focus on a different incoming message instead of having two or more trying to receive the same one. Is there a way to achieve this?
I don't know if this helps but I am currently using Iprobe() to check for incoming messages and Irecv() with Test() to check if the thread has received the whole message.
Starting with version 3 of the standard, MPI allows for the removal of matched messages from the message queue so that they are no longer visible to subsequent probes/receives. This is done using the so-called matched probes. Just replace MPI_Iprobe with MPI_Improbe, which is the non-blocking matched probe operation:
int flag;
MPI_Status status;
MPI_Message msg;
MPI_Improbe(source, tag, comm, &flag, &msg, &status);
Once MPI_Improbe returns 1 in flag, a message matching (source, tag, comm) has arrived. A handle to the message is stored into msg and the message is removed from the queue. Subsequent probes or receives with a matching (source, tag, comm) triplet - by the same thread or in another - won't see the same message again and therefore won't interfere with its reception by the thread that matched it originally.
To receive a matched message, use MPI_Imrecv (or the blocking MPI_Mrecv):
MPI_Request req;
MPI_Imrecv(buffer, count, dtype, &msg, &req);
do
{
...
MPI_Test(&req, &flag, &status);
}
while (!flag);
Versions of MPI before 3.0 do not provide similar functionality. But, if I understand you correctly, you only need to guarantee that no matching probe will be posted before MPI_Irecv has had the opportunity to remove the message from the queue (which is what matched probe+receive is meant to prevent). If you are probing in a master thread and then dispatching the messages to different threads, then you could use a semaphore to delay the execution of the next probe by the main thread until after the worker has issued MPI_Irecv. If you have multiple threads doing probe+receive, then you may simply issue the MPI_Irecv call in the same critical section (or whatever synchronisation primitive you use to achieve the serialisation of the MPI calls as required by MPI_THREAD_SERIALIZED) as MPI_Iprobe once the probe turns out successful:
// Worker thread
CRITICAL(mpi)
{
MPI_Iprobe(source, tag, comm, &flag, &status);
if (flag)
MPI_Irecv(buffer, count, dtype, status.MPI_SOURCE, status.MPI_TAG, comm, &req);
}
Replace the CRITICAL(name) { ... } notation with whatever primitives your programming environment provides.
If I understand you correctly it's not the matter how you receive messages but how you send them. As you can see below MPI_Send function has destination parameter which defines to which thread this message will be sent.
MPI_Send(
void* data,
int count,
MPI_Datatype datatype,
int destination,
int tag,
MPI_Comm communicator)
So if you wan to make certain threads receive certain messages you have to send this messages only to that thread.

PostThreadMessage fails

I have created a UI thread. I m posting message to the UI thread which will write data in a file.
I am using PostThreadMessage API to post the message to User thread. My Problem is it's not writing all the data that I have posted. For Instance, if i post 100 data, it writes randomly 3 or 98 varies for every execution. The handler for Postdata is not getting called for every message.
CWriteToFile *m_pThread = (CWriteToFile *)AfxBeginThread(RUNTIME_CLASS (CWriteToFile));
PostThreadMessage(m_pThread->m_nThreadID , WM_WRITE_TO_FILE, (WPARAM)pData,NULL);
WaitForSingleObject(m_pThread, INFINITE);
The Return value of PostThreadMessage is success.
The PostMessage family of functions can fail if the message queue is full. You should check whether or not the function call succeeds.

PostThreadMessage returns ERROR_INVALID_THREAD_ID

I have a multi-threaded simulation running on Windows Vista. When I use PostThreadMessage to send messages between threads, I am getting ERROR_INVALID_THREAD_ID, even though I am quite certain (from stepping through the debugger) that the thread id is valid, and the thread has a message queue, since I call PeekMessage from every thread after I create them, as specified in MSDN. It's likely the target thread is suspended, but that should not be a problem, as far as I can tell.
Any clues on what to try? I am simulating an RTOS based application, so I'm hoping not to have to put in too much Windows specific code.
EDIT -
Another clue - if I remove all the semaphore blocking, the messages work fine (although there are some known race conditions). But message queues should not be affected by thread blocking, right?
Edit 2
The code also has the following retry mechanism, as suggested by MSDN. But it still does not work - the retry always fails. hmmm.....
BOOL bResult = false;
int retry = 0;
DWORD dwError = 0;
do
{
bResult = PostThreadMessage(pTaskHandle->dwThreadID,0,0,(LPARAM)pMessage);
if (!bResult)
{
dwError = GetLastError();
retry++; // should only happen once, if the dest thread has no msg queue
// the retry establishes the queue
Sleep(500);
}
} while (!bResult && retry<3); // MSDN says try this a few times to start msg queue
You mention you call PeekMessage after creating the threads but do these threads have full, active message processing loops that are dispatching the messages? msdn says:
Call PostThreadMessage. If it fails, call the Sleep function and call PostThreadMessage again. Repeat until PostThreadMessage succeeds.
which sounds a little goofy if the only requirement is that the thread called PeekMessage once.
Also be aware that messages posted via. PostThreadMessage don't get dispatched in DispatchMessage. this seems obvious since there's no window for the message to go to, but I've seen people do it, especially when using MsgWaitForMultipleObjects and such to wait on a handle. in this case it seems unlikely you'd get ERROR_INVALID_THREAD_ID... more likely you'd just miss the message.

Resources