В многопоточности этот пункт
if(!p_inst)
{
p_inst = new Singleton();
}
на самом деле 3 отдельных действия. Вы получаете значение p_inst
, устанавливаете значение p_inst
и записываете значение p_inst
. Таким образом, get-set-write означает, что вам нужно поставить блокировку вокруг p_inst
, иначе вы можете иметь 2 потока, которые создают значение Singleton
, которое использует каждый поток.
Вот как вы можете просмотреть проблему, предположим, что у вашего Singleton
есть изменяемое поле val
:
thread A -> p_inst is NULL
thread B -> p_inst is NULL
thread A -> set to Singleton (1)
thread B -> set to Singleton (2)
thread C -> p_inst is Singleton (2)
thread A -> set val to 4
thread B -> set val to 6
thread C -> get val (it's 6)
thread A -> get val (it's 4!!)
Видишь? Есть 2 копии Синглтона, ни одна из которых не знает о другой. Третий поток, который проверяет Singleton
, увидит только последнее назначение. Но с блокировкой вы можете предотвратить многократное назначение и подобные проблемы.