Почему не ссылочный счетчик в повышении:: энергозависимый shared_ptr?

В boost::shared_ptr деструктор, это сделано:

if(--*pn == 0)
{
    boost::checked_delete(px);
    delete pn;
}

где pn указатель на ссылочный счетчик, который является typedefed как

shared_ptr::count_type -> detail::atomic_count -> long

Я ожидал бы long быть volatile long, поданный распараллелил использование и неатомарный 0-check-and-deletion shared_ptr деструктор выше. Почему это не энергозависимо?

Править:

Оказывается, что я посмотрел на заголовок, используемый, когда многопоточное использование не указано (atomic_count.hpp). В atomic_count_win32.hpp декремент правильно реализован для многопоточного использования.

6
задан Johann Gerell 26 March 2010 в 11:56
поделиться

3 ответа

Потому что volatile не нужен для многопоточности, и не делает ничего полезного, но потенциально уничтожает ряд оптимизаций.

Чтобы обеспечить безопасный многопоточный доступ к переменной, нам нужен примитив - барьер памяти, который обеспечивает как гарантии volatile, так и некоторые другие (он предотвращает переупорядочивание доступа к памяти через барьер, чего не делает volatile)

Я считаю, что shared_ptr использует атомарные операции, когда это возможно, которые неявно обеспечивают барьер памяти. В противном случае он возвращается к мьютексу, который также обеспечивает барьер памяти.

См. Почему volatile не считается полезным в многопоточном программировании на C или C++? или http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/ для более подробной информации

Редактировать
count_type является не long в общем случае. Он конвертируется в long. Если вы посмотрите в atomic_count.hpp, типизация к long применяется только в том случае, если нет потоковой обработки (в этом случае, конечно, синхронизация не нужна). В противном случае используется реализация, определенная в boost/smart_ptr/detail/atomic_count_pthreads.hpp или boost/smart_ptr/detail/atomic_count_win32.hpp или в одном из других перечисленных файлов. И это синхронизированные классы-обертки, которые гарантируют, что все операции выполняются атомарно.

16
ответ дан 8 December 2019 в 04:08
поделиться

volatile практически не имеет ничего общего с потоками. См. здесь .

8
ответ дан 8 December 2019 в 04:08
поделиться

Вы неправильно читаете код. atomic_count определяется просто как long, если код не использует многопоточность:

#ifndef BOOST_HAS_THREADS

namespace boost
{

namespace detail
{

typedef long atomic_count;

}

}

#elif //... include various platform-specific headers that define atomic_count class

#endif
2
ответ дан 8 December 2019 в 04:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: