Почему все кол беки boost Asio выполняются в одном потоке, хотя io_context запущен в нескольких потоках?
В коде ниже представлен асинхронный сервер, который принимает сообщение от клиента, печатает сообщение в консоль, отправляет клиенту сообщение ok и сново слушает сокет. На каждом шаге я вывожу id потока, и это id всегда = 1. Я запускаю обработку в 10 потоках, но обработка все равно проходит в одном потоке, как это исправить?
#include <iostream>
#include <functional>
#include <memory>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
using boost::asio::ip::tcp;
class Session {
private:
tcp::socket sock;
std::string message;
uint16_t maxMessageLength;
private:
Session(boost::asio::io_context& context, uint16_t maxMessageLength);
public:
typedef std::shared_ptr<Session> SessionSharedPtr;
public:
static SessionSharedPtr CreateNewSession(boost::asio::io_context& context, short messageLength = 2048);
void ReceiveMessage(std::function<void(const boost::system::error_code&, size_t)>);
void SendMessage(std::string message,
std::function<void(const boost::system::error_code&, size_t)> handler);
std::string& GetMessage();
tcp::socket& GetSocket();
~Session();
};
Session::Session(boost::asio::io_context &context, uint16_t maxMessageLength) : sock(context)
{
this->maxMessageLength = maxMessageLength;
message.resize(maxMessageLength);
}
Session::SessionSharedPtr Session::CreateNewSession(boost::asio::io_context &context, short messageLength) {
return Session::SessionSharedPtr(new Session(context, messageLength));
}
Session::~Session() {
sock.close();
}
std::string &Session::GetMessage() {
return message;
}
tcp::socket &Session::GetSocket() {
return sock;
}
void Session::ReceiveMessage(std::function<void(const boost::system::error_code&, size_t)> handler) {
sock.async_read_some(boost::asio::buffer(message, maxMessageLength), handler);
}
void
Session::SendMessage(std::string messageToSend, std::function<void(const boost::system::error_code &, size_t)> handler) {
sock.async_write_some(boost::asio::buffer(messageToSend, messageToSend.length()), handler);
}
boost::asio::io_context context;
tcp::acceptor acceptor(context, tcp::endpoint(tcp::v6(), 8000));
void acceptHandle(Session::SessionSharedPtr session, const boost::system::error_code& err){
session->ReceiveMessage([=](const boost::system::error_code& err, size_t byte){
std::cout << "thread_id(receive): " << boost::this_thread::get_id << std::endl;
if (err)
std::cout << "fail receive" << std::endl;
else {
std::cout << byte << std::endl;
std::cout << session->GetMessage();;
}
});
session->SendMessage("ok", [](const boost::system::error_code &err, size_t byte) {
std::cout << "thread_id:(send) " << boost::this_thread::get_id << std::endl;
if (err)
std::cout << "fail send" << std::endl;
else{
std::cout << "send: " << byte << std::endl;
}
});
auto newSession = Session::CreateNewSession(context);
std::cout << "thread_id:(accept) " << boost::this_thread::get_id << std::endl;
acceptor.async_accept(newSession->GetSocket(), std::bind(acceptHandle, newSession, std::placeholders::_1));
}
int main() {
Session::SessionSharedPtr session = Session::CreateNewSession(context);
acceptor.async_accept(session->GetSocket(), std::bind(acceptHandle, session, std::placeholders::_1));
const size_t threadNum = 10;
boost::thread_group threads;
for (size_t i = 0; i < threadNum; i++){
threads.create_thread([](){
context.run();
});
}
threads.join_all();
return 0;
}