Безопасна ли передача параметров в лямбда-захвате для повышения потока сообщений / отправки asio? - PullRequest
0 голосов
/ 12 ноября 2018

Я использую lambda's capture для передачи параметров в boost::asio::io_context::post обратный вызов.
Это потокобезопасно?

Код

#include <iostream>
#include "boost/asio.hpp"
#include <thread>

int main() {
    boost::asio::io_service io_service;
    boost::asio::io_service::work work(io_service);

    std::thread t([&](){
        io_service.run();
    });

    auto var = 1;
    io_service.post([&io_service, var]() {
        std::cout << "v: " << var << std::endl;
        io_service.stop();
    });

    t.join();

    return 0;
}

Как видите,Я передаю var в lambda's capture.main thread устанавливает значение var, а поток t читает его.
Я не использовал ни один из memory ordering, например, std::memory_order_release после установки var в 1std::memory_order_acquire до чтения значения var.Более того, я не думаю, что могу - потому что переменная var передается по значению в lambda.

Безопасно ли это делать?
Если нет, как это должно бытьсделано?

1 Ответ

0 голосов
/ 13 ноября 2018

Это потокобезопасный.

Объект закрытия создается основным потоком (с копированием значения var) после создания и инициализации var. Затем объект замыкания передается в качестве аргумента методу post, который ставит этот объект в очередь и сразу же возвращается без вызова функтора. Функтор вызывается между post и t.join звонками - post гарантирует это. Таким образом, ваш код должен быть потокобезопасным.

Вам потребуется какой-то метод синхронизации (например, использование mutex + lock_guard). если var передано по ссылке [1] и некоторым операциям записи на var [2] были совершены между post и t.join вызовами:

auto var = 1;
io_service.post([&io_service, &var]() { // [1] takes by reference
    std::cout << "v: " << var << std::endl; // lock mutex for printing
    io_service.stop();
});
var = 10; // [2] , lock mutex for writing
// synchronization must be added because between post and t.join calls,
// reading and writing operations are executed
t.join();

в этом случае вам придется защищать var.

...