When calling create_task is there a way to ensure that the task doesn't run on the UI thread?
I want to be sure I'm not inadvertently calling wait inside a task that somehow managed to execute on the UI thread.
The create_task function won't spontaneously jump onto the UI thread: if you don't call it from the UI thread it won't execute there. You need to explicitly call the Dispatcher to get back.
An apartment aware task (one which returns IAsyncAction or IAsyncOperation) will continue in its apartment by default if a task_continuation_context isn't provided to tell it otherwise. The common case of starting a task on a UI thread will continue on the UI thread.
See the Managing the thread context section of MSDN's Asynchronous programming in C++ docs for more details.
Related
Back to stackoverflow with another question after hours of trying on my own haha.
Thank you all for reading this and helping in advance.
Please note the console program has following functionalities:
connect to a frame grabber
apply some configs
store the incoming data (640 * 480 16-bit grayscale imgs) in a stream of buffers inside a while loop
Exits the while loop upon a key press.
disconnect from device
And I'm only adding the displaying the images functionality on the MFC GUI app. In short,
i) Converting a console app to an MFC app (dialog based)
ii) decided to use thread for displaying images, but DK how to properly exit from thread when there are certain tasks to be done (such as call disconnectFromDevice(); freeBuffers();, etc) before exiting the thread.
iii) have tried making the while loop condition false but didn't work
( I actually want this to be a callback function that's called repeatedly but IDK how to implement it inside a thread)
iv) forcing AfxEndThread didn't work and it's not even the way it should be done (I think).
So my question is,
1. Are you supposed to use a while loop to excuete a certain job that should repeatedly be done? If not, do you have to implement a callback inside a thread? Or use Windows message loop? Why and how? Please provide a hello-world-like sample code example
(for example, you are printing "hello world" repeatedly inside a thread with a condtion in an MFC GUI app. How do you update or check the condition to end the thread if you can't just AfxEndThread() inside the threadproc)
2. If it's ok with a while, how do you exit from the while loop, in other words how do you properly update the exit condition outside the thread the while loop's in?
Please refer to the source code in the provided link
ctrl+F OnBnClickedConnectButton, AcquireImages and OnBnClickedDisconnectButton
https://github.com/MetaCortex728/img_processing/blob/main/IR140Dlg.cpp
Worker threads do not have message-queues, the (typically one and only) UI one does. The message-queue for a thread is created by the first call of the GetMessage() function. Why use messages to control processing in a worker thread? You would have to establish a special protocol for this, defining custom messages and posting them to the queue.
Worker threads can be implemented as a loop. The loop can be terminated based on various conditions, like failures to retrieve any data or request from the user. You can simply exit the thread proc to terminate the thread's execution. If the thread doesn't respond it may have stuck (unless it performs a really lengthy operation) and the UI thread must provide some mechanism to kill it. That is first request termination and if it doesn't respond within some set time then kill it.
The condition mechanism to terminate should best be some synchronization object (I would recommend a manual-reset event), interlocked variable or a simple boolean which you should access and set using a critical section.
Some considerations:
You pass a parameter block to the thread. Make sure that it remains alive throughout the thread's lifetime. For example, it should NOT be a local variable in a function that exits before the thread's termination.
The loop must be "efficient", ie do not loop infinitely if data are not available. Consider using blocking functions with timeouts, if available.
Resource management (eg connecting/disconnecting, allocating/releasing etc) should best be performed by the same thread.
An alternative implementation can be APCs. Then the thread's proc function is a while(!bTerminate) { SleepEx(INFINITE, TRUE); } loop, and other threads issue requests using a the QueueUserAPC() function.
The AfxEndThread(0) call in OnBnClickedDisconnectButton() is wrong, it terminates the current thread, which in this case is the main (UI) thread. Check the documentation.
A sidenote, my suggestion about the project type is not a dialog-based application but instead a normal MFC application without a document class (uncheck the Document/View architecture support option), as it offers features like menus, toolbars and the like, and most importantly the ON_UPDATE_COMMAND_UI handlers.
I'm on some c++ mobile product, but I need my apps main thread is still running without any blocking when doing some heavy work on the background thread and run back on main thread. But I realized there is no runOnMainThread/runOnUIThread in c++ thread api. I trying to figure it out the issue and found that need to depend library, or create your own thread event queue. Although it is good, but i am thinking to have a behavior which can runOnUIThread.
How it does not work: the mentioned library creates a timer, installs a SIGALRM signal handler and dispatches queued tasks when signals are fired. This allows tasks being processed on the main thread even when it is busy. However POSIX permits only a small set of async-signal-safe functions to be invoked inside of signal handler. Running arbitrary с++ code inside of signal handler violates that restriction and leaves application in hopelessly doomed state.
After some research and development, I've created a library called NonBlockpp
it is a small c++ library to allow c++ mobile application able to process the heavy and time consuming task on background and back to Main thread again, It’s been tested and fired the main thread event.
It also allow to save the tasks and fire them later, all the task has no blocking each other and thread safety.
How it works:
If you found any query or suggestion, please don't hesitate to raise an issue and we can discuss it together.
The project has rectify from signal to pollEvent due to signal handler might not be safe to use.
Please take a look the new changed.
NonBlockpp
Usage
I have written a C++ class that encapsulates a web browser (inspired by this). One of the class methods takes HTML code as a string and renders it in the browser. The browser's rendering is asynchronous, and in some situations it is necessary to wait until document loading is complete before proceeding. I am uncertain of whether I am doing this correctly.
What I do is open a new document, call IHTMLDocument2::put_onreadystatechange (passing an instance of an EventSink class that I implemented), and call IHTMLDocument2::write to render the desired HTML. This is all done in the main thread.
The main thread then continues with other things. After a while, when the ready state changes, the browser calls EventSink::Invoke. There, I call IHTMLDocument2::get_readyState and check whether it equals complete. This also happens in the main thread (called by COM via the client stub, if my understandung is correct).
The problem is that although I detect when document loading is complete, the main thread has been doing other things in the mean time, possibly accessing the HTML DOM. So I would like to wait for document completion immediately after calling IHTMLDocument2::write. How does one achieve this? I can't set an event semaphore in the event sink and wait for it, because both pieces of code are executed by the main thread. So should I really be using a worker thread here? I'm somewhat confused about which thread would do what. E.g. the thread invoked by the COM client stub would set the event semaphore when loading is complete, but which thread is that - always the main thread, or the thread that created the COM object? Any help is appreciated.
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 am using wxwidgets together with boost::thread. The Thread is a worker thread which sends some Events to the GUI:
Thread creation:
thrd = boost::thread(boost::bind(workerFunction,this));
Send Message to the GUI:
wxPostEvent(loWindow, event);
wxSafeYield();
Under Windows I don't see any problems, but when starting the application under Linux (Ubuntu 8.10), it stops with the following error message:
_XCBUnlockDisplay: Assertion `xcb_get_request_sent(dpy->xcb->connection) == dpy->request' failed.
Aborted
What am I missing? When the workerFunction is not started in a thread, it works without problems.
Regards,
/mspoerr
Don't call wxYield from a worker thread. Only do that from the GUI thread. Yield will process gui events, and is intended to be used if in some GUI event handler you do much of work and want to update other controls and process pending events in between. The Safe in wxSafeYield means that it disables GUI controls before it processes pending events first. That will protect you from such cases like entering the event handler you called wxYield from a second time, recursively. It doesn't mean that it is thread-safe, or something like that.
If you want to give the rest of the time slice your thread would have to other threads, call wx's wxThread::Yield or boost's this_thread::yield (depending on your thread class) instead.
The problem was with the data I sent - for complex data you need to use custom events. I now implemented a custom event and it works.
For more information please see http://forums.wxwidgets.org/viewtopic.php?t=24663
Thank you for your help!
/mspoerr
EDIT: Updated the link. The old one was broken