Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost asio single threaded post() doesn't post when poll() is used?

Tags:

c++

boost

asio

Everything is handle in a single thread

void GameClient::test()
{
   std::cout <<"called test" << std::endl;
    m_io_context.post([](){
        std::cout << "test" << std::endl;
    });
}

void GameClient::calledFromALoop()
{
    // Use poll instead of run to avoid blocking
    auto count = m_io_context.poll();
    std::cout << "polled: " << count << std::endl;
}

I want every async task to be handled in calledFromALoop() function. It is called from a loop around 50 times per second.

This is the output:

...
polled: 0
polled: 0
polled: 0
called test
polled: 0
polled: 0
polled: 0
...

Can you help me understand why the lambda in post isn't executed ? This is a minimal example, originally in the test function, I use async_resolve, but I have the same behavior.

I don't want to use run() because I don't want calledFromALoop() to block.

But then I don't really understand when the async function is executed (not the handler). For example I assume async_resolve need some work to set up the resolution, then some time to perform network operation, then the handler (callback). When do these steps are executed ?
I think the set up is done at the call of async_resolve, then network time, then the callback is called from poll(). Am I right ?
Using run() instead of poll() will block during the network time.

The weird behavior is if I change the position of this line auto count = m_io_context.poll(); like this:

void GameClient::test()
{
   std::cout <<"called test" << std::endl;
    m_io_context.post([](){
        std::cout << "test" << std::endl;
    });
    m_io_context.poll();
}

void GameClient::calledFromALoop()
{
    
}

I have called test test as expected !

like image 567
Nathan Avatar asked Sep 03 '26 21:09

Nathan


1 Answers

Sure it does:

Live On Coliru

#include <boost/asio.hpp>
#include <iostream>
namespace asio = boost::asio;

int main() {
    asio::io_context ioc(1);

    post(ioc, [] { std::cout << "Hello, world!" << std::endl; });

    ioc.poll();
}

Prints

Hello, world!

Running Out Of Work

Like others commented, you might let the service run out of work. You must prevent that or reset() it.

asio::io_context ioc(1);

post(ioc, [] { std::cout << "Hello, world!" << std::endl; });
ioc.poll();

post(ioc, [] { std::cout << "Hello, world!" << std::endl; });
ioc.poll(); // doesn't print anything

However, e.g.:

auto work = make_work_guard(ioc);

post(ioc, [] { std::cout << "Hello, world!" << std::endl; });
ioc.poll();

post(ioc, [] { std::cout << "Hello, world!" << std::endl; });
ioc.poll(); // prints!
like image 190
sehe Avatar answered Sep 05 '26 10:09

sehe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!