Though I am quoting this in context of Borland C++ application, but the question is both specific for Borland as well as generic in nature.
In a Borland C++ project, I observe that a user interaction with the GUI (say a menu item click) is taking less priority than a task delegated to the main thread using Synchronize(), even though the user interaction is happening a few milliseconds earlier. When the main thread is available, the delegated task is done first and then the action corresponding to the user interaction is performed. A worker thread delegates a task to main thread and waits for the task to complete using Synchronize(). So we can equate Synchronize() to SendMessage().
I believe that the user interaction queues up as a message in the message queue and same should be the case with the delegated task. But how does the task execute first? Is there any priority between messages?
Up to and including C++Builder 5, Synchronize() did indeed make a call to SendMessage(). But in C++Builder 6, Synchronize() was re-written to not use SendMessage() anymore (to support Linux under CLX). Requests are now placed in a FIFO queue, and the VCL periodically calls CheckSynchronize() to process the queue. Even though CLX is long dead, Synchronize() still uses the same FIFO queue (and it has been enhanced over the years).
Aside from that, in cases where SendMessage() is used, it does have higher priority. User interactions are posted messages to the main thread message queue (aka PostMessage()). Although SendMessage() goes directly to a window's wndproc, it is not called until the receiving window's owning thread performs message processing if sent by a different thread (which used to be the case with Synchronize()). Pending SendMessage() requests to the main thread message queue have higher priority than pending posted messages to the same queue, as there are other threads/processes being blocked until the pending SendMessage() requests are processed.
Related
I have an operation which ends in about 20 seconds. To avoid freezing, I want to create a thread and update a label text in it every second. I searched a lot, since everyone has different opinion, I couldn't decide which method to use.
I tried SendMessage and it works but some people believe that using SendMessage is not safe and I should use PostMessage instead. But PostMessage fails with ERROR_MESSAGE_SYNC_ONLY (1159).
char text[20] = "test text";
SendMessage(label_hwnd, WM_SETTEXT, NULL, text);
I searched about this and I think it's because of using pointers in PostMessage which is not allowed. That's why it fails.
So, what should I do? I'm confused. What do you suggest? Is this method is good for change UI elements in other thread?
Thanks
The documentation for ERROR_MESSAGE_SYNC_ONLY says:
The message can be used only with synchronous operations.
This means that you can use synchronous message delivery, i.e. SendMessage and similar, but you cannot use asynchronous message delivery, i.e. PostMessage.
The reason is that WM_SETTEXT is a message whose parameters include a reference. The parameters cannot be copied by value. If you could deliver WM_SETTEXT asynchronously then how would the system guarantee that the pointer that the recipient window received was still valid?
So the system simply rejects your attempt to send this message, and indeed any other message that has parameters that are references.
It is reasonable for you to use SendMessage here. That will certainly work.
However, you are forcing your worker thread to block on the UI. It may take the UI some time to update the caption's text. The alternative is to post a custom message to the UI thread that instructs the UI thread to update the UI. Then your worker thread thread can continue its tasks and let the UI thread update in parallel, without blocking the worker thread.
In order for that to work you need a way for the UI thread to get the progress information from the worker thread. If the progress is as simple as a percentage then all you need to do is have the worker thread write to, and the UI thread read from, a shared variable.
Well, the error says it all. The message cannot be sent asynchronously. The thing about PostMessage is that it posts the message to the listening thread's queue and returns immediately, without waiting for the result of message processing. SendMessage on the other hand, waits until the window procedure finishes processing the message and only then it returns.
The risk of using PostMessage in your case is that before window procedure processes the message you may have deallocated the string buffer. So it is safer to use SendMessage in this instance and that's what MS developers probably thought about when they decided not to allow asynchronous posting of this particular message.
EDIT: Just to be clear, of course this doesn't eliminate the risk of passing a naked pointer totally.
From MSDN
If you send a message in the range below WM_USER to the asynchronous message functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its message parameters cannot include pointers. Otherwise, the operation will fail.
The asynch PostMessage() alternative requires that the lifetime of the data passed in the parameters is extended beyond the message originator function. The 'classic' way of doing that is to heap-allocate the data, PostMessage a pointer to it, handle the data in the message-handler in the usual way and then delete it, (or handle it in some other way such that it does not leak). In other words, 'fire and forget' - you must not touch the data in the originating thread after the PostMessage has been issued.
The upside is that PostMessage() allows the originating thread to run on 'immediately' and so do further work, (maybe posting more messages). SendMessage() and such synchronous comms can get held up if the GUI is busy, imacting overall throughput.
The downside is that a thread may generate mesages faster than the GUI can process them. This usually manifests to the by laggy GUI responses, especially when performing GUI-intenisve work like moving/resizing windows and updating TreeViews. Eventually, the PostMessage call will fail when 10,000+ messages are queued up. If this is found to be a problem, additional flow-control may have to be added, so further complicating the comms, ( I usually do that by using a fixed-size object pool to block/throttle the originating thread if all available objects are stuck 'in transit' in posted, but unhandled, messages.
I think you can use SendMessage safely here. Then you don't need to worry about memory persistence for your string and other issues.
SendMessage is not safe when you send messages from another message handler or send message to blocked GUI thread, but if in your case you know it is safe - just use it
This is not a problem with the PostMessagebut a problem with the message you are sending - WM_SETTEXT. First a common misconception is that if you SendMessage() to a control from a thread, it is different from calling GUI API, it is in fact NOT. When you call a GUI API (from anywhere) for example to set text, windows implement this in the form of SendMessage() call. So when you are sending the same message, it is essentially same as calling the API. Although directly GUI access like this works in many ways it is not recommended. For this reason, I would beg to disagree with the accepted answer by #David.
The correct way is (code on the fly)
char* text = new char[20]
strcpy_s(text, "test text");
PostMessage(label_hwnd, IDM_MY_MSG_UPDATE_TEXT, NULL, text);
you will updated the text in your own message IDM_MY_MSG_UPDATE_TEXT handler function and delete the memory.
I'm just curious as to to how to implement multi-threading without using a Windows API WaitFor* function that stops the program until the thread has returned. What's the point of using threads if they stop the main application from being resized or moved etc.?
Is there any form of windows messaging with threading, which will allow me to call my thread function and then return, and handle the return values of the thread when it finishes running?
If you want your UI thread to know when a task thread has finished it's task then you could have your task thread post a (custom - WM_USER and above) message to your main window (along with thread id plus the handle). And the window proc of the main window can know that a particular task thread has finished it's task. This way the UI thread does not have to wait actively (using WaitFor*) on the thread(s) object.
You can use MsgWaitForMultipleObjectsEx to wait for the thread to finish and also process messages at the same time.
Have a look at std::thread, boost::thread, just::thread, for multithreading in general for c++.
But about Windows messaging win32 and MFC, the MSDN states explicitely that it is not multithread, it is monothread. ( Undefined behaviour is to be expected if multithreading is used)
For asynchronous message emited in other thread than the main application window thread, you should use ::PostMessage(), that will insert message events in the monothread message pump of the mono threaded window.
WaitForSingleObject can be non-blocking, just pass zero timeout as second parameter:
// Check is thread has been finished
if(::WaitForSingleObject(threadHandle, 0) == WAIT_OBJECT_0)
{
// Process results
...
}
You will need to periodically check this condition, e.g. on timer or after processing any message in message loop.
Or you can use MsgWaitForMultipleObjectsEx. It will unblock and return when some message/input event occured in calling thread message queue.
As other answers mentioned there is another way - using Windows asynchronously posted message to signal that thread has done its work. This way has disadvantage - the working thread must know target window or thread to post message to. This dependency complicates design and raises issues about checking thread/window lifetime. To avoid it message broadcasting (PostMessage(HWND_BROADCAST,...))
can be used, but this is overkill for your case, I don't recommend it.
I'm currently playing with the Asynchronous Agents Library in Microsoft's Concurrency Runtime. I have not yet found an obvious way to signal that a task is finished by using window messages, or some other means of notifying the UI thread that the work is finished.
I know I can pass window handles and message values (WM_xxx) along to the tasks, and have the task use PostMessage() to signal the UI thread. This is somewhat ugly in my opinion, and a source of error. If an exception occurs, I have to have a catch handler that signals my UI thread. This is easily forgotten, and the exception condition might not be run very often, so it's hard to spot it.
The documentation talks about how to move data back to the UI thread. It does not make use of window messages, but polling techniques. I find it silly to set up timers to poll if a task has finished, when there are "interrupt" methods available!
It's kind of odd that this isn't built into the library, as it's not a cross platform library. It's designed to run on Windows, and Windows only, from what I understand.
Is the functionality available in the library, or do I have to hand roll this?
You can create one monitor thread with sole function of monitoring an unbounded_buffer for a windows message and dispatching that message appropriately. Have your agents know about this buffer.
We have an API that handles event timers. This API says that it uses OS callbacks to handle timed events (using select(), apparently).
The api claims this order of execution as well:
readable events
writable events
timer events
This works by creating a point to a Timer object, but passing the create function a function callback:
Something along these lines:
Timer* theTimer = Timer::Event::create(timeInterval,&Thisclass::FunctionName);
I was wondering how this worked?
The operating system is handling the timer itself, and when it sees it fired how does it actually invoke the callback? Does the callback run in a seperate thread of execution?
When I put a pthread_self() call inside the callback function (Thisclass::FunctionName) it appears to have the same thread id as the thread where theTimer is created itself! (Very confused by this)
Also: What does that priority list above mean? What is a writable event vs a readable event vs a timer event?
Any explanation of the use of select() in this scenario is also appreciated.
Thanks!
This looks like a simple wrapper around select(2). The class keeps a list of callbacks, I guess separate for read, write, and timer expiration. Then there's something like a dispatch or wait call somewhere there that packs given file descriptors into sets, calculates minimum timeout, and invokes select with these arguments. When select returns, the wrapper probably goes over read set first, invoking read callback, then write set, then looks if any of the timers have expired and invokes those callbacks. This all might happen on the same thread, or on separate threads depending on the implementation of the wrapper.
You should read up on select and poll - they are very handy.
The general term is IO demultiplexing.
A readable event means that data is available for reading on a particular file descriptor without blocking, and a writable event means that you can write to a particular file descriptor without blocking. These are most often used with sockets and pipes. See the select() manual page for details on these.
A timer event means that a previously created timer has expired. If the library is using select() or poll(), the library itself has to keep track of timers since these functions accept a single timeout. The library must calculate the time remaining until the first timer expires, and use that for the timeout parameter. Another approach is to use timer_create(), or an older variant like setitimer() or alarm() to receive notification via a signal.
You can determine which mechanism is being used at the OS layer using a tool like strace (Linux) or truss (Solaris). These tools trace the actual system calls that are being made by the program.
At a guess, the call to create() stores the function pointer somewhere. Then, when the timer goes off, it calls the function you specified via that pointer. But as this is not a Standard C++ function, you should really read the docs or look at the source to find out for sure.
Regarding your other questions, I don't see mention of a priority list, and select() is a sort of general purpose event multiplexer.
Quite likely there's a framework that works with a typical main loop, the driving force of the main loop is the select call.
select allows you to wait for a filedescriptor to become readable or writable (or for an "exception" on the filedeescriptor) or for a timeout to occur. I'd guess the library also allow you to register callbacks for doing async IO, if it's a GUI library it'll get the low primitive GUI events via a file descriptor on unixes.
To implement timer callbacks in such a loop, you just keep a priority queue of timers and process them on select timeouts or filedescriptor events.
The priority means it processes the file i/o before the timers, which in itself takes time, could result in GUI updates eventually resulting in GUI event handlers being run, or other tasks spending time servicing I/O.
The library is more or less doing
for(;;) {
timeout = calculate_min_timeout();
ret = select(...,timeout); //wait for a timeout event or filedescriptor events
if(ret > 0) {
process_readable_descriptors();
process_writable_descriptors();
}
process_timer_queue(); //scan through a timer priority queue and invoke callbacks
}
Because of the fact that the thread id inside the timer callback is the same as the creator thread I think that it is implemented somehow using signals.
When a signal is sent to a thread that thread's state is saved and the signal handler is called which then calls the event call back.
So the handler is called in the creator thread which is interrupted until the signal handler returns.
Maybe another thread waits for all timers using select() and if a timer expires it sends a signal to the thread the expired timer was created in.
I'm importing a portion of existing code into my Qt app and noticed a sleep function in there. I see that this type of function has no place in event programming. What should I do instead?
UPDATE: After thought and feedback I would say the answer is: call sleep outside the GUI main thread only and if you need to wait in the GUI thread use processEvents() or an event loop, this will prevent the GUI from freezing.
It isn't pretty but I found this in the Qt mailing list archives:
The sleep method of QThread is protected, but you can expose it like so:
class SleeperThread : public QThread
{
public:
static void msleep(unsigned long msecs)
{
QThread::msleep(msecs);
}
};
Then just call:
SleeperThread::msleep(1000);
from any thread.
However, a more elegant solution would be to refactor your code to use a QTimer - this might require you saving the state so you know what to do when the timer goes off.
I don't recommend sleep in a event based system but if you want to ...
You can use a waitcondition, that way you can always interrupt the sleep if neccesary.
//...
QMutex dummy;
dummy.lock();
QWaitCondition waitCondition;
waitCondition.wait(&dummy, waitTime);
//...
The reason why sleep is a bad idea in event based programming is because event based programming is effectively a form on non-preemptive multitasking. By calling sleep, you prevent any other event becoming active and therefore blocking the processing of the thread.
In a request response scenario for udp packets, send the request and immediately wait for the response. Qt has good socket APIs which will ensure that the socket does not block while waiting for the event. The event will come when it comes. In your case the QSocket::readReady signal is your friend.
If you want to schedule an event for some point of time in the future, use QTimer. This will ensure that other events are not blocked.
It is not necessary to break down the events at all. All I needed to do was to call QApplication::processEvents() where sleep() was and this prevents the GUI from freezing.
I don't know how the QTs handle the events internally, but on most systems at the lowest level the application life goes like this: the main thread code is basically a loop (the message loop), in which, at each iteration, the application calls a function that gives to it a new message; usually that function is blocking, i.e. if there are no messages the function does not return and the application is stopped.
Each time the function returns, the application has a new message to process, that usually has some recipient (the window to which is sent), a meaning (the message code, e.g. the mouse pointer has been moved) and some additional data (e.g. the mouse has been moved to coords 24, 12).
Now, the application has to process the message; the OS or the GUI toolkit usually do this under the hood, so with some black magic the message is dispatched to its recipient and the correct event handler is executed. When the event handler returns, the internal function that called the event handler returns, so does the one that called it and so on, until the control comes back to the main loop, that now will call again the magic message-retrieving function to get another message. This cycle goes on until the application terminates.
Now, I wrote all this to make you understand why sleep is bad in an event driven GUI application: if you notice, while a message is processed no other messages can be processed, since the main thread is busy running your event handler, that, after all, is just a function called by the message loop. So, if you make your event handler sleep, also the message loop will sleep, which means that the application in the meantime won't receive and process any other messages, including the ones that make your window repaint, so your application will look "hang" from the user perspective.
Long story short: don't use sleep unless you have to sleep for very short times (few hundreds milliseconds at most), otherwise the GUI will become unresponsive. You have several options to replace the sleeps: you can use a timer (QTimer), but it may require you to do a lot of bookkeeping between a timer event and the other. A popular alternative is to start a separate worker thread: it would just handle the UDP communication, and, being separate from the main thread, it would not cause any problem sleeping when necessary. Obviously you must take care to protect the data shared between the threads with mutexes and be careful to avoid race conditions and all the other kind of problems that occur with multithreading.