Поскольку 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
- это , а не a long
в общем случае. конвертируется в long
. Если вы посмотрите на atomic_count.hpp
, typedef to long применяется только в том случае, если нет потоков, доступных (в этом случае, конечно, синхронизация не требуется). В противном случае он использует реализацию, определенную в boost/smart_ptr/detail/atomic_count_pthreads.hpp
или boost/smart_ptr/detail/atomic_count_win32.hpp
или в одном из других перечисленных файлов. И это синхронизированные классы-обертки, которые гарантируют, что все операции выполняются атомарно.