2 Copyright Oliver Kowalke 2013.
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt
8 [section:asio Example: asynchronous network I/O (boost.asio)]
10 In the past, code using asio's ['asynchronous operations] was scattered by
12 __boost_asio__ provides with its new ['asynchronous result] feature a new way to
13 simplify the code and make it easier to read.
14 __yield_context__ internally uses __boost_coroutine__:
16 void echo(boost::asio::ip::tcp::socket& socket,boost::asio::yield_context yield){
18 // read asynchronous data from socket
19 // execution context will be suspended until
20 // some bytes are read from socket
21 std::size_t n=socket.async_read_some(boost::asio::buffer(data),yield);
22 // write some bytes asynchronously
23 boost::asio::async_write(socket,boost::asio::buffer(data,n),yield);
26 Unfortunately __boost_coroutine__ (__yield_context__) does not provide
27 primitives to synchronize different coroutines (execution contexts).
29 __boost_fiber__ provides an example how __fibers__ could be integrated into
30 __boost_asio__ so that ['asynchronous operations] from __boost_asio__ can be
31 used together with fibers, synchronized by primitives provided by
34 The example section contains a complete publish-subscribe application
35 demonstrating the use of fibers with asio's ['asynchronous operations].
36 __yield_fiber__ abstracts the fiber in asio's context.
38 void subscriber::run( boost::fibers::asio::yield_fiber yield)
40 boost::system::error_code ec;
42 // read first message == channel name
44 boost::asio::async_read(
46 boost::asio::buffer( channel),
48 if ( ec) throw std::runtime_error("no channel from subscriber");
50 // register new channel
51 reg_.subscribe( channel, shared_from_this() );
55 boost::fibers::mutex::scoped_lock lk( mtx_);
56 // wait for published messages
57 // fiber gets suspended and will be woken up if a
58 // new message has to be published to subscriber
61 // '<fini>' terminates subscriber
62 // data_ is a private member of subscriber and
63 // gets filled by the publisher
64 // notification of available data via condition_var cond_
65 if ( "<fini>" == std::string( data_) ) break;
67 // write message asynchronously to subscriber
68 // fiber gets suspended until message was written
69 boost::asio::async_write(
71 boost::asio::buffer( data_, max_length),
73 if ( ec) throw std::runtime_error("publishing message failed");
77 [heading C10K problem]
79 The C10K-website [footnote [@http://www.kegel.com/c10k.html 'The C10K problem',
81 from Dan Kegel describes the problem of handling ten thousand clients
82 simultaneously and which strategies are possible.
84 __boost_fiber__ and __boost_asio__ support the strategy 'serve many clients with
85 each server thread, and use asynchronous I/O' without scattering the logic
86 across many callbacks (as was asio's previous strategy) and overloading the
87 operating system with too many threads. (Beyond a certain number of threads, the
88 overhead of the kernel scheduler starts to swamp the available cores.)
90 Because __boost_fiber__ contains synchronization primitives, it is easy to
91 synchronize different fibers and use asynchronous network I/O at the same
94 __boost_fiber__ provides the same classes and interfaces as __boost_thread__.
95 Therefore developers are able to use patterns familiar from multi-threaded
96 programming. For instance the strategy 'serve one client with one thread'
97 could be transformed into 'serve one client with one fiber'.
101 The code for integrating boost.fiber int boost.asio can be found in the example
102 directory. The author believes, that a better, more tight integration is
103 possible but requires input of boost.asio's author and maybe some changes in the
104 boost.asio framework.
106 The current integration pattern requires to runn __io_service__ in
107 __run_service__ (separate fiber).