Can Boost::asio::post can interrupt the running thread? - c++

I am new to Boost::asio and I am currently looking at io_context.
I have a question regarding the function io_context::post
Posting on thread can preempt what's running on that thread currently ?
because in the documentation i have seen :
Deprecated: Use post.) Request the io_context to invoke the given handler and return immediately.
I'm expecting that post will be added to the event queue, and will only be considered to run again when control is passed back to the event loop

No it cannot interrupt the running thread(s) associated with the io_context. post() enqueues the task to the io_context which will execute it eventually. The "return immediately" is meant in terms of the post() call itself, not the task. So the post() function returns immediately without blocking, but the task is scheduled for later execution.

Related

When does a PPL task execute on the UI thread?

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.

DBUS - multithread processing

I have a main loop in my program, which calls this method from dbus:
dbus_connection_read_write_dispatch
I have some registered callbacks, which are invoked, when message arrives. Within this callback I am also processing the response and sending back response. Problem is that sometimes it takes much time so probably it will block receiving messages from DBUS.
Question - can I call dbus_connection_read_write_dispatch() method on the same connection from more than one thread? Then it will be probably possible to receive new DBUS messages while the previous one is being processed.
Or maybe better idea is to process responses in another thread than the main loop, from callback is invoked?
Thank you
you can call dbus_connection_read_write_dispatch() from multiple threads if you have called the function dbus_threads_init_default() atleast once.Instead a better approach is to have a single thread running dbus dispatcher and use a thread-pool to process the data from callbacks.
See dbus_threads_init_default() for more info.
By the document provided by freedesktop.org, you can.
But if you operate with same DBusConnection instance from different threads directly, eg. calling dbus_connection_send_with_reply_and_block in a thread while anothoer thread is blocking on dbus_connection_read_write_dispatch, the connection maybe work unproperly. According to official document, DBus connection will be locked when calling callback functions.DBusConnection
In my situation, the dbus_connection_send_with_reply_and_block didn't return even if the return message was send to my process (I had seen it on dbus-monitor). Calling dbus_thread_init does not work at all.
Recently I used a delegate to send / receive / dispatch all dbus messages in one thread, and problem disappeared.
A mail in mailing list of freedesktop.org

What is the definition of a boost::asio::io_service ready handler?

I am trying to understand the difference between io_service's poll()/poll_one() and run()/run_one(). The difference as stated in the documentation is that poll() executes ready handlers as opposed to run() which executes any handler.
But nowhere in the boost documentation could I find the definition of a 'ready handler'.
A valid answer to this question is one able to show, preferably with a code example, the difference between a ready and non-ready handler and the difference between how poll() and run() executes it.
Thanks.
A "ready handler" is a handler that is ready to be executed. If you have issued an asynchronous call, it gets executed in the background and its handler becomes ready when the async call is done. Before that, the handler is pending, but not ready.
poll_one executes one ready handler if there is any.
poll executes all ready handlers, but not the pending. Both poll versions return immediately after the execution of the handlers.
run_one executes a ready handler if there is one, if not it waits for the first pending handler to become ready, meaning it blocks.
run executes and waits, until there are neither ready nor pending handlers. After it returns, the io_servie is in stopped state.
See also Boost::Asio : io_service.run() vs poll() or how do I integrate boost::asio in mainloop
int main()
{
boost::asio::io_service io_service;
boost::asio::deadline_timer timer(io_service);
timer.expires_from_now(boost::posix_time::seconds(5));
timer.async_wait([](const boost::system::error_code& err)
{ std::cout << (err ? "error" : "okay")
;});
//io_service.poll_one();
io_service.run_one();
}
If you use io_service.poll_one(); you will most likely not see any output because the timer has not elapsed yet. ready handler simply means a handle that is ready to run (such as when a timer elapses or an operation finishes, etc.). However, if you use io_service.run_one(); this call will block until the timer finishes and execute the handler.

Windows Api Multi-threading Messages

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.

Boost async_read_some not exactly asynchronous

This is my server code:
socket_.async_read_some(boost::asio::buffer(data_read.data(), Message::header_length),
boost::bind(&TcpConnection::handle_read_header, shared_from_this(),
boost::asio::placeholders::error));
If i write a the the following code in a loop
boost::thread::sleep(boost::posix_time::seconds(2));
in the 'handle_read_header' function which is called by the above 'async_read_some' the whole thread is waiting till the sleep end. So when another request comes in it is not handled until the sleep finishes. Isn't is suppose to asynchronously handles each requests? I am new to boost and C++. Please let me know if i have mentioned anything wrong.
Read scheduled with async_read_some is realized in the thread which called io_service::run().
If you have only one thread it will wait for completing one read handler, before starting another one.
You can make a thread pool, by running more threads with io_service::run() or make the execution of read handler shorter.