Утечка памяти при перемещении функции в поток (используя лямбду) - PullRequest
0 голосов
/ 22 марта 2019

У меня есть код ниже, который использует uWebSockets в качестве библиотеки для моего бэкэнда. Теперь я хочу правильно завершить работу, это приводит к утечке памяти (для проверки используйте valgrind ).

#include <App.h>

#include <thread>
#include <chrono>

int main()
{
    using namespace std::chrono_literals;

    us_listen_socket *token{};

    auto start_server = [&token] {
        uWS::App()
            .listen(9001, [&token](auto *listenSocket) {
                if (listenSocket) token = listenSocket;
            })
            .run();
    };

    auto start_timer = [&token] {
        std::this_thread::sleep_for(2s);
        us_listen_socket_close(token);
    };

    ...
}

... выглядит следующим образом:

Версия с утечкой:

std::thread(start_server).detach();
start_timer();

Бесплатная версия:

std::thread(start_timer).detach();
start_server();

Я знаю, что программа протекает, только когда я перемещаю код для запуска сервера в отдельный поток, но я не могу понять причину этого.

1 Ответ

0 голосов
/ 22 марта 2019

Если я правильно понимаю ваш код, тогда обе версии имеют неопределенное поведение, потому что у вас есть два потока, которые одновременно обращаются к объекту token, один из которых пишет в него, а другой читает из него.Я не уверен, какова цель попытки закрыть token через ровно 2 секунды;но что бы это ни было, вам придется использовать правильную синхронизацию, например, использовать std::mutex для защиты доступа к token или, по крайней мере, сделать token атомарным .Затем программа продолжит утечку, поскольку это зависит только от того, потребуется ли кому-то более 2 секунд для подключения (я предполагаю, что это происходит здесь) или нет, но по крайней мере утечка будет четко определенным поведением…

...