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?
~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.