This problem seems to be related to threads and running the program very quickly. I have 2 classes, ThreadParent and ThreadChild where one inherits from another. ThreadParent creates a thread and runs the function func, declared as static to circumvent pointer problems. I do however want that the inherited classes such as ThreadChild decide what the thread exactly does so func calls the virtual function Do.
When creating a ThreadChild object however and immediately running the thread calls ThreadParent::Do once at the start, and all following calls are ThreadChild::Do. Interestingly, when I wait a bit before calling Do, it does not happen.
Is there a better solution than to wait a bit? And more importantly, why does this happen?
Here is a small, but complete example. It creates a ThreadChild object which executes Do every 200ms. The program ends after 1s (waiting for an enter press).
#include <iostream>
#include <windows.h>
#include <thread>
// The parent class
class ThreadParent {
protected:
bool _loopThread; //setting this to false should end the thread
std::thread _thread; //the thread
public:
// Basic constructor
ThreadParent(ThreadParent* child)
: _loopThread(true),
_thread(func, child, &_loopThread) {}
// Stops the thread and waits for it to finish
void StopThread() {
_loopThread = false;
_thread.join();
}
protected:
// The function the thread will be running (static because of pointer issues)
static void func(ThreadParent* child, bool* loopThread) {
//Sleep(10); //<- uncomment to solve the problem?
while (*loopThread) {
child->Do(); // Do is called every 200ms
Sleep(200);
}
}
// The function which is called repeatedly until _loopThread is set to false
virtual void Do() {
std::cout << "Parent call\n";
}
};
// The child class
class ThreadChild : public ThreadParent {
public:
// Basic constructor
ThreadChild()
: ThreadParent(this) {}
protected:
// Redefines Do() with another message
void Do() {
std::cout << "Child call\n";
}
};
// The program
int main() {
ThreadChild thread; // Create and run the thread
Sleep(1000); // Run the thread for 1s
thread.StopThread(); // End it
std::cout << "Press <enter> to terminate...";
std::cin.get(); // Wait for user to end program
return 0;
}
Output:
Parent call
Child call
Child call
Child call
Child call
Press <enter> to terminate...