Я хочу использовать pword() для хранения дополнительного объекта с любым потоком, но потокобезопасным способом, а именно для выделения
ровно одного экземпляр объекта в первый раз для данного потока. Поскольку void*, на который ссылается pword(), не является атомарным и, следовательно, не может использовать функцию сравнения-обмена, я считаю, что мне придется использовать блокировку с двойной проверкой и барьерами памяти. Используя это в качестве отправной точки, у меня есть:
Код: Выделить всё
class my_obj { /* ... */ };
my_obj* get_obj_for( std::ios_base &b ) {
static int const index = ios_base::xalloc();
void *p = b.pword( index );
std::atomic_thread_fence( std::memory_order_acquire );
if ( p == nullptr ) {
static std::mutex mutex;
std::lock_guard lock{ mutex };
p = b.pword( index );
if ( p == nullptr ) {
p = new my_obj;
std::atomic_thread_fence( std::memory_order_release );
b.pword( index ) = p;
}
}
return static_cast( p );
}
Однако в примере «Использование ограждений получения и освобождения C++11», приведенном в этой статье, его указатель m_instance равен std::atomic. Будет ли мой приведенный выше код по-прежнему потокобезопасным, даже если void*, на который ссылается pword(), не std::atomic? Если нет, есть ли способ сделать код потокобезопасным?
Подробнее здесь:
https://stackoverflow.com/questions/782 ... d-safe-way