I am having a bit of multi-threading issues with some of my code. The ManagedObject class implements "lazy-initialization", which uses the Initialize method to initialize its state. Every accessor calls Initialize. This is because the initialization can be quite costly for the performance.
Now in a single threaded environment my implementation below has no issues, but in my current situation it can be accessed from multiple threads, so they can both start the Initialization process at the same time.
It gets invalidated 60-100 times a second and does the initialization process again when some other thread tries to access data from the managed object. Because multiple threads can ask for data on the same object the initialization can overlap and mess things up badly.
Would really appreciate if someone could point me at some best practises here!
#include <iostream>
#include <windows.h>
#include <thread>
#include <atomic>
#include <string>
#include <mutex>
using namespace std;
class ManagedObject
{
protected:
std::atomic<bool> initialized = false;
public:
void Initialize(std::string name)
{
if (initialized) return;
// this code should only be ran once. Since initialized can still be false, other threads may start initializing as well, this should not happen.
Sleep(500);
cout << name << ": Initializing 1" << endl << endl;
Sleep(500);
initialized = true;
}
void Invalidate()
{
initialized = false;
}
bool IsActive(std::string name)
{
Initialize(name);
return true;
}
};
int main()
{
auto object1 = make_shared<ManagedObject>();
std::thread([&] {
object1->IsActive("Thread 1");
}).detach();
std::thread([&] {
object1->IsActive("Thread 2");
}).detach();
Sleep(5000);
return 0;
}
The output of this program is:
Thread 1: Initializing 1
Thread 2: Initializing 1
The expected output should be only one thread initializing, while the other waits for the initialized state without doing the initialization process itself.
Aucun commentaire:
Enregistrer un commentaire