Я столкнулся со следующей проблемой:
У меня есть класс RpcExecutor
.Этот класс:
- отправляет запросы RPC
- получает ответы RPC
Я сохраняю все асинхронно (через boost.asio).Каждый раз, когда отправляется запрос, будет вызываться обработчик записи, который изменяет карту:
async_write(...., [this, ...](error_code ec, size_t bytesTransferred) {
//
pendingRequests_.insert(requestId, move(myPromise));
};
Я начинаю слушать в том же сокете, с async_read_until
, и приходят ответы, возможно, не в порядке.Мне также нужно изменить pendingRequests_
от этого пользователя:
async_read(... [this, ...](error_code ec, size_t bytesTransferred) {
...
pendingRequests_.at(requestId).set_value(...);
pendingRequests_.erase(requestId);
});
Мой класс выглядит так:
class RpcExecutor {
private:
std::unique_ptr<std::map<std::uint64_t, MyPromise>> pendingRequests_;
...
};
Чтобы убедиться, что инициализация pendingRequests_
,чтение и запись pendingRequests_
выполняются в одном и том же потоке (я проверял, что это так), применяются следующие ограничения:
- работает один поток
asio::run()
,который отличается от RpcExecutor
instance. - Я инициализирую
pendingRequests_
наведенный объект внутри boost::asio::post(myIoContext, ...)
, что означает, что он инициализируется в том же потоке, где выполняется asio::run
. - Обработчик
async_read
и обработчик async_write
выполняются в том же потоке, что и io_context::run
, который совпадает с boost::asio::post
.
Всего всего:
boost::asio::post
, async_read
обработчик и async_write
обработчик выполняются в одном потоке. RpcExecutor
экземпляр класса создается в другом потоке.
Результат
async_read
и обработчик async_write
не видят один и тот же адрес памяти для pendingRequests_
.
Вопросы
- Как мне инициализировать
map
, который я могу использовать из своего потока обработчиков, учитывая, что экземпляр класса RpcExecutor
находится в другом потоке?Даже если я инициализирую указанный элемент в том же потоке, что и asio::context::run
через post
, обработчики по-прежнему видят разные адреса для объекта. - Нужны ли мне мьютексы любого вида?На самом деле я хочу сделать все операции чтения / записи из одного потока, даже если он не совпадает с потоком экземпляра класса
RpcExecutor
, который содержит переменную-член pendingTasks_
.