Как известно, классический синглтон Мейерса не является потокобезопасным.
После осознания этого факта, программист проходит обычно следующую цепочку действий:
1) Вставляет критическую секцию на все тело метода “получение экземпляра”
2) Осознает, что это неэффективно, и применяет double-check lock
3) Обнаруживает, что double-check lock не обеспечивает 100% потокобезопасность, и начинает это лечить (см. volatile, memory barriers и т.п.)
Грустная правда заключается в том, что, поскольку в нынешней версии стандарта С++ ничего нет на тему потоков, решения которое было бы абсолютно переносимо на любую платформу (компилятор + ОС + железо) не существует. На эту тему есть статья Мейерса. Однако для VC++ и IA32-64 есть вполне простое работающее решение (к сожалению, в статье об этом не говорится, поэтому она производит неоднозначное впечатление).
Дискуссии на эту тему есть здесь:
http://rsdn.ru/forum/cpp.applied/3545271.aspx
http://www.rsdn.ru/forum/cpp.applied/3234750.all.aspx
http://www.rsdn.ru/forum/cpp/531461.flat.4.aspx
http://rsdn.ru/forum/cpp.applied/3545271.aspx
. В общем и целом, достаточно классического double-check lock + применения volatile – указателей на создаваемый объект + приравнивания статического указателя на объект к свежесозданному объекту через 1) временную переменную 2) InterlockExchange с этой временной переменной. На указанной архитектуре и с указанным компилятором это приведет к барьерам памяти в нужных местах. Попозже выложу код.