многопоточность — Является ли управление ресурсами в деструкторе для классов / статических элементов одного состояния плохой идеей в C ++?

Я пытаюсь реализовать класс 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 дает тот же результат, но без ошибок. Нить просто продолжает работать.

Постскриптум


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

0

Решение

 ~test();

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

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

1

Другие решения

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

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

1

По вопросам рекламы [email protected]