Является ли управление ресурсами в деструкторе классов-моностатов или статических членов плохой идеей в C ++? - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь реализовать класс monostate, который управляет некоторым std :: thread.Поток работает, пока флаг не станет равным false.После изменения флага на false - поток останавливается.Но похоже, что я должен вызывать метод остановки явно.Вызов его в деструкторе приносит мне ошибки времени выполнения (протестировано на GCC 4.8 для ARM, GCC 4.9 для x86_64 и MSVC 2017).Прав ли я, что такое поведение обусловлено

"Статические члены класса не связаны с объектами класса: они являются независимыми объектами со статической продолжительностью хранения или обычными функциями, определенными в области пространства имен,только один раз в программе. "

, поэтому вызов деструктора пропущен?

Пример кода:

#include <iostream>
#include <chrono>
#include <thread>
#include <atomic>


void runThread(const std::atomic<bool> &_isRunning) {

    while (_isRunning) {

        std::cout << "Me running.." << std::endl;

        std::this_thread::sleep_for(std::chrono::milliseconds(30));

    }

}

class test {

    static std::thread          thread;
    static std::atomic<bool>    isRunning;


public:

    test();
    ~test();

    static void go();
    static void stop();


};

std::thread         test::thread;
std::atomic<bool>   test::isRunning{ false };


test::test() {}

void test::go() {

    isRunning = true;
    thread = std::thread(runThread, std::ref(isRunning));

}

void test::stop() {

    isRunning = false;

    if (thread.joinable()) {

        thread.join();

    }

}

test::~test() {

    stop();

}


int main() {

    test::go();

    std::this_thread::sleep_for(std::chrono::seconds(5));

    std::cout << "Done here!!!!!!!!!!!!!!!!!";

    // Will not crash anymore if uncomment
    //test::stop();

    return 0;

}

Использование std :: async с std :: featureдает тот же результат, но без ошибок.Поток просто продолжает работать.

PS


Создание класса non-monostate решает ошибки времени выполнения, но оставляет меня с этим вопросом.Является ли управление ресурсами плохой практикой для моностатических классов / статических членов?

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Конструктор статического объекта вызывается до выполнения main, а деструктор вызывается после завершения main (обычно из atexit).

Поместите точку останова в деструктор, это легко увидеть.

0 голосов
 ~test();

должен быть вызван перед уничтожением любого "тестового" объекта. Вы не создаете «тестовые» объекты в своем коде, поэтому вы правы,

Статические члены класса не связаны с объектами класс: это независимые объекты со статической продолжительностью хранения или обычные функции, определенные в области имен, только один раз в программа.

...