-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarification Needed on Thread Context Switch in writer() Function (example streaming-server.cpp) #88
Comments
Hi, the comment in the code is in fact accurate. Asio describes the thread-switching behavior in their documentation. Although I find it rather difficult to understand, let me try to explain it in my own words. Take the following example: asio::io_context io_context1;
asio::steady_timer timer{io_context1};
asio::io_context io_context2;
asio::co_spawn(
io_context2,
[&]() -> asio::awaitable<void>
{
// on io_context2 thread
// Timer is handled on io_context1 thread
// But after completion it will:
// `asio::dispatch(asio::get_associated_executor(use_awaitable_completion_handler,
// timer.get_executor()), use_awaitable_completion_handler)`
// which causes the switch back to io_context2 thread
co_await timer.async_wait(asio::use_awaitable);
// on io_context2 thread
},
asio::detached);
auto g = asio::make_work_guard(io_context1);
std::thread t{[&]
{
io_context1.run();
}};
io_context2.run();
g.reset();
t.join(); Asio performs the following steps on this line
Since asio-grpc tries to mimic Asio's behavior as much as possible, replacing I hope that helps, let me know if something is still unclear. |
Hi, Thank you for the clear explanation. I tested it and everything worked just as you described. Your guidance made the thread-switching behavior in Asio much clearer. Also, I want to say that asio-grpc is an amazing project. Really appreciate all the work you've put into it. Best |
Thanks, glad I could help. Btw, you can disable the thread-switching this way: inline void use_inline_awaitable() { return asio::bind_executor(asio::system_executor(), asio::use_awaitable); }
co_await timer.async_wait(use_inline_awaitable()); This will cause |
Hi again, I revisited your example and noticed that after co_await timer.async_wait(), the execution returns to the io_context2 thread, the same thread as before the co_await. So, in the writer code, before co_await rpc.write(), it's in the thread_pool, right? By the same logic, does this mean that after co_await rpc.write(), the execution also returns to the thread_pool? |
It doesn't matter what thread it was on before the co_await, what matters is the first argument passed to |
Great, it's finally clear now. Thank you so much. |
|
Correct, the asio::co_spawn(asio::get_associated_executor(completion_handler, first_argument_passed_to_register_awaitable_rpc_handler()) Asio internally always works with executors. There is a |
Hello,
I'm currently reviewing the server-side code for handling gRPC requests, specifically the use of co_await rpc.write(response); in the writer() coroutine function. I observed that there is a comment stating "// Now we are back on the main thread." after this line of code.
From my understanding, in Asio and C++ coroutines, the execution context or thread does not automatically switch back to the original context (such as the main thread of grpc_context) after an await operation, unless explicitly specified. However, in this instance, I don't see an explicit switch back to the grpc_context after the write operation in a multi-threaded environment (using asio::thread_pool).
Could you please clarify if the comment accurately reflects the behavior of the code? If there is indeed an automatic switch back to the main grpc_context thread happening, could you point out where and how this context switch is being handled in the code?
This clarification will greatly help in understanding the correct thread behavior and context management in asynchronous operations within the application.
Thank you for your time and assistance.
The text was updated successfully, but these errors were encountered: