Mam zaimplementowałem singleton (wersja statyczna) w C++. Znam wszystkie kontrowersje na temat tego wzorca i potencjalnych problemów związanych z bezpieczeństwem wątków, ale jestem ciekawy, dlaczego ta dokładna implementacja nie zatrzyma się. Program nigdy się nie kończy, pozostaje na końcu w stanie zakleszczenia.Dlaczego ten statyczny singleton C++ nigdy się nie zatrzymuje?
singleton.h:
#pragma once
#include <thread>
#include <atomic>
class Singleton
{
public:
static Singleton& getInstance();
private:
std::thread mThread;
std::atomic_bool mRun;
Singleton();
~Singleton();
void threadFoo();
};
singleton.cpp
#include "singleton.h"
Singleton& Singleton::getInstance()
{
static Singleton instance;
return instance;
}
Singleton::Singleton()
{
mRun.store(true);
mThread = std::thread(&Singleton::threadFoo, this);
}
Singleton::~Singleton()
{
mRun.store(false);
if(mThread.joinable())
mThread.join();
}
void Singleton::threadFoo()
{
while(mRun)
{
}
}
main.cpp
#include "singleton.h"
int main()
{
Singleton::getInstance();
return 0;
}
Co już wiem:
- wątek kończy
- główny wątek utknął w łączeniu
- ma coś wspólnego ze statycznym, jeśli sprawię, że konstruktor będzie publiczny i utworzy instancję Singleton w main(), to poprawnie się zakończy.
Korzystanie z programu Visual Studio 2012. Dziękujemy za porady.
Mieszanie globalnego zamykania i uruchamiania wątków jest trudne w najlepszym wypadku . W tej chwili nie mogę znaleźć żadnego standardowego odniesienia, ale podejrzewam, że to, co próbujesz zrobić (czy wątek przeszedł przez koniec) jest tak naprawdę niezdefiniowanym zachowaniem. –
Prawdopodobnie dlatego, że instancja statyczna przeżyje 'main()'. – juanchopanza
czy zachowuje się tak samo, jeśli konstruktor jest publiczny i tworzy go jako lokalną zmienną główną? – kassak