boost::asio::io_service:在等待将来时将控制权返回到 IO 服务的运行

boost::asio::io_service: return control to IO service's run while waiting for future

本文关键字:返回 控制权 IO 服务 运行 io asio service 将来 在等待 boost      更新时间:2023-10-16

我有一个通过第三方IO服务调用的方法。我的方法应该返回一个布尔值。但是,我需要将另一个任务发布到相同的IO服务,并等待它完成后才能知道结果。当我等待其他任务完成时,我如何将控制返回到IO循环?

(我可以添加多个线程,但可能会有多个调用我的方法,你仍然会以死锁结束)

之前的调用图:

<thread>    io_service               third_party    my_stuff
   |            |                        |             |
   |---run----->|                        |             |
   |            |-->some_posted_method-->|             |
   |            |                        |--callback-->|
   |            |                        |<--boolean---|
   |            |(next task)             |             |
   |            |                        |             |

呼叫图首选:

<thread>    io_service               third_party    my_stuff
   |            |                        |             |
   |---run----->|                        |             |
   |            |-->some_posted_method-->|             |
   |            |                        |--callback-->|
   |            |<----some_way_to_return_control-------|
   |            |(next task)             |             |
   |            |--------some_kind_of_resume---------->|
   |            |                        |<--boolean---|
   |            |                        |             |

"third_party"应该异步调用"my_stuff",指定一个处理程序,该处理程序将在结果准备好后立即继续,并将控制权返回给io_service。"third_party"在这里有点令人担忧,因为你可能无法修改它,或者它不可取。

另一种方法是为"my_stuff"使用另一个io_service实例:"my_stuff"接口将是同步的,但实现将在相同或另一个线程中使用io_service来完成其任务。从来没有尝试过,但我没有看到任何问题,从我所知道的Boost.Asio。

就像Tanner Sansbury提到的,您可以从事件处理程序调用poll_one,它将执行可用的处理程序。

注意你必须调用poll_one,因为如果不断添加新的处理程序,poll不能保证返回。由于poll_one可能还没有准备好执行的处理程序,您可能需要添加一个睡眠以防止繁忙的等待。我的代码是这样结束的:

while( !syncDone ) {
    boost::system::error_code  ec;
    int handlersExecuted = ioService.poll_one(ec);
    if( ec ) {
        //Not sure what error there could be, log it
    }
    if( 0 == handlersExecuted ) {
        std::this_thread::sleep_for(
            std::chrono::milliseconds(10)
        );
    }
}