J'ai rencontré l'implémentation suivante de la fonction Singleton get_instance
fonction :
template<typename T>
T* Singleton<T>::get_instance()
{
static std::unique_ptr<T> destroyer;
T* temp = s_instance.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);
if (temp == nullptr)
{
std::lock_guard<std::mutex> lock(s_mutex);
temp = s_instance.load(std::memory_order_relaxed);/* read current status of s_instance */
if (temp == nullptr)
{
temp = new T;
destroyer.reset(temp);
std::atomic_thread_fence(std::memory_order_release);
s_instance.store(temp, std::memory_order_relaxed);
}
}
return temp;
}
Et je me demandais si les barrières mémorielles d'acquisition et de libération présentaient un intérêt quelconque ? Pour autant que je sache, les barrières de mémoire sont destinées à empêcher le réordonnancement des opérations de mémoire entre deux variables différentes. Prenons l'exemple classique :
(Tout ceci est en pseudo-code - ne vous laissez pas surprendre par la syntaxe)
# Thread 1
while(f == 0);
print(x)
# Thread 2
x = 42;
f = 1;
Dans ce cas, nous voulons empêcher la réorganisation des deux opérations de stockage dans le Thread 2, et la réorganisation des deux opérations de chargement dans le Thread 1. Nous insérons donc des barrières :
# Thread 1
while(f == 0)
acquire_fence
print(x)
# Thread 2
x = 42;
release_fence
f = 1;
Mais dans le code ci-dessus, quel est l'avantage des clôtures ?
EDITAR
La principale différence entre ces deux cas est que, dans l'exemple classique, nous utilisons des barrières de mémoire puisque nous avons affaire à des 2 variables - nous avons donc le "danger" du stockage du fil 2 f
avant le stockage x
ou, alternativement, le danger de chargement dans le fil 1 x
avant le chargement f
.
Mais dans mon code Singleton, quelle est la réorganisation possible de la mémoire que les barrières de mémoire visent à empêcher ?
NOTA
Je sais qu'il y a d'autres moyens (et peut-être de meilleurs) d'y parvenir, ma question est à des fins éducatives - je me renseigne sur les barrières mémorielles et je suis curieux de savoir si, dans ce cas particulier, elles sont utiles. Je suis curieux de savoir si, dans ce cas particulier, elles sont utiles.