A tiny library & examples for join boost::fiber&boost::asio toghter.
This library works in this design:
- boost::asio runs in some threads;
- boost::fibers runs in other threads (May include the main thread);
- use
boost::asio::fibers::use_futurefor every asio async call placeholder. - the fibers will yield when
future.getcalled, and weakup when value fullfill or exception occured. - with threads helpers, these fibers & asio threads can be easy managed in main thread.
- Support Boost 1.70.0 now!
- Fiber thread manager add
postfunction for none fiber thread move jobs.
- Use
boost::asio::fibers::use_futureas placeholders when call asio async functions. - Call the returned
future.get()when need to wait the async call done. - Fiber will yield until the async call done or exception throws.
This example convert from asio::use_future.
void get_daytime(boost::asio::io_context& io_context, const char* hostname) { try { udp::resolver resolver(io_context); boost::fibers::future<udp::resolver::results_type> endpoints = resolver.async_resolve( udp::v4(), hostname, "daytime", boost::asio::fibers::use_future); // The async_resolve operation above returns the endpoints as a future // value that is not retrieved ... udp::socket socket(io_context, udp::v4()); std::array<char, 1> send_buf = {{ 0 }}; boost::fibers::future<std::size_t> send_length = socket.async_send_to(boost::asio::buffer(send_buf), *endpoints.get().begin(), // ... until here. This call may block. boost::asio::fibers::use_future); std::cout << "Endpoint get" << std::endl; // Do other things here while the send completes. std::cout << "Sended: " << send_length.get() // Blocks until the send is complete. Throws any errors. << std::endl; std::array<char, 128> recv_buf; udp::endpoint sender_endpoint; boost::fibers::future<std::size_t> recv_length = socket.async_receive_from( boost::asio::buffer(recv_buf), sender_endpoint, boost::asio::fibers::use_future); // Do other things here while the receive completes. std::cout.write( recv_buf.data(), recv_length.get()); // Blocks until receive is complete. } catch (std::system_error& e) { std::cerr << e.what() << std::endl; } } Then use it as a fiber:
int main() { ... boost::fibers::fiber([&io_context, address]{ get_daytime(io_context, address) }); ... }These articals give me the idea to write this tiny library.