Search code examples
c++multithreadingc++11stdthreadmonostate

Is managing resources in destructor for monostate classes/static members a bad idea in C++?


I'm trying to implement monostate class which manages some std::thread. Thread is running until flag become equals to false. After flag changes to false - thread stops. But looks like I have to call stoping method explicitly. Calling it in destructor brings me runtime errors (Tested on GCC 4.8 for ARM, GCC 4.9 for x86_64 and MSVC 2017). Am I right that such behavior is due to

"Static members of a class are not associated with the objects of the class: they are independent objects with static storage duration or regular functions defined in namespace scope, only once in the program."

so destructor call is omited?

Code sample:

#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;

}

Using std::async with std::feature gives same result but without error. Thread just keeps running.

P.S.


Making the class non-monostate solves runtime errors but leaves me with this question. Is managing resources a bad practice for monostate classes/static members?


Solution

  •  ~test();
    

    should be called before destroying any "test" object. You do not create "test" objects in your code, so you are right,

    Static members of a class are not associated with the objects of the class: they are independent objects with static storage duration or regular functions defined in namespace scope, only once in the program.