开发者

Boost::Asio : io_service.run() vs poll() or how do I integrate boost::asio in mainloop

I am currently trying to use boost::asio for some simple tcp networking for the first time, and I allready came across something I am not really sure how to deal with. As far as I understand io_service.run() method is basically a loop which runs until there is nothing more left to do, which means it will run until I release my little server object. Since I allready got some sort of mainloop set up, I would rather like to update the networking loop m开发者_Python百科anually from there just for the sake of simplicity, and I think io_service.poll() would do what I want, sort of like this:

void myApplication::update()
{
     myIoService.poll();
     //do other stuff
}

This seems to work, but I am still wondering if there is a drawback from this method since that does not seem to be the common way to deal with boost::asios io services. Is this a valid approach or should I rather use io_service.run() in a non blocking extra thread?


Using io_service::poll instead of io_service::run is perfectly acceptable. The difference is explained in the documentation

The poll() function may also be used to dispatch ready handlers, but without blocking.

Note that io_service::run will block if there's any work left in the queue

The work class is used to inform the io_service when work starts and finishes. This ensures that the io_service object's run() function will not exit while work is underway, and that it does exit when there is no unfinished work remaining.

whereas io_service::poll does not exhibit this behavior, it just invokes ready handlers. Also note that you will need to invoke io_service::reset on any subsequent invocation to io_service:run or io_service::poll.


A drawback is that you'll make a busy loop.

while(true) {
    myIoService.poll()
}

will use 100% cpu. myIoService.run() will use 0% cpu.

myIoService.run_one() might do what you want but it will block if there is nothing for it to do.


A loop like this lets you poll, doesn't busy-wait, and resets as needed. (I'm using the more recent io_context that replaced io_service.)

while (!exitCondition) {
    if (ioContext.stopped()) {
        ioContext.restart();
    }
    if (!ioContext.poll()) {
        if (stuffToDo) {
            doYourStuff();
        } else {
            std::this_thread::sleep_for(std::chrono::milliseconds(3));
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜