Reputation: 35
Regarding this post: Why do I need strand per connection when using boost::asio?
I'm focusing on this statement regarding async calls: "However, it is not safe for multiple threads to make calls concurrently"
This example: http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/chat/chat_client.cpp
If I refer to main as "thread 1" and the spawned thread t as "thread 2", then it seems like thread 1 is calling async_write (assuming no write_in_progress) while thread 2 is calling async_read. What am I missing?
Upvotes: 0
Views: 1534
Reputation: 51881
In the official chat example, chat_client::write()
defers work to the io_service
via io_service::post()
, which will:
io_service
execute the given handler via a thread that is currently invoking the poll()
, poll_one()
, run()
, or run_one()
function on the io_service
chat_client::write()
)As only one thread is running the io_service
, and all socket read, write, and close operations are only initiated from handlers that have been posted to the io_service
, the program satisfies the thread-safety requirement for socket
.
class chat_client
{
void write(const chat_message& msg)
{
// The nullary function `handler` is created, but not invoked within
// the calling function. `msg` is captured by value, allowing `handler`
// to append a valid `msg` object to `write_msgs_`.
auto handler = [this, msg]()
{
bool write_in_progress = !write_msgs_.empty();
write_msgs_.push_back(msg);
if (!write_in_progress)
{
do_write();
}
};
// Request that `handler` be invoked within the `io_service`.
io_service_.post(handler);
}
};
Upvotes: 2