簡體   English   中英

為什么boost :: shared_ptr中的引用計數器不是volatile?

[英]Why isn't the reference counter in boost::shared_ptr volatile?

boost::shared_ptr析構函數中,完成了:

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

其中pn是指向引用計數器的指針,該引用計數器的類型為

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

考慮到線程的使用以及上面的shared_ptr析構函數中的非原子0檢查和刪除,我本來期望long可以volatile long 為什么不變化?

編輯:

事實證明,我查看了未指定多線程使用時使用的標頭(atomic_count.hpp)。 在atomic_count_win32.hpp中,為多線程用法正確實現了減量。

因為volatile不是多線程所必需的,並且沒有任何益處,但可能會破壞許多優化。

為了確保對變量的安全多線程訪問,我們需要的原語是一個內存屏障,它既提供了volatile的保證又提供了其他一些(它阻止了內存訪問重新排序跨越屏障,volatile不會這樣做)

我相信shared_ptr盡可能使用原子操作,這隱含地提供了內存屏障。 否則它會回落到互斥鎖,這也會提供內存屏障。

請參閱為什么在多線程C或C ++編程中volatile不被認為有用? http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/了解更多詳情

編輯
count_type在一般情況下 long 它可以轉換成很long 如果你查看atomic_count.hpp ,只有在沒有可用的線程時才會應用typedef to long(在這種情況下,當然不需要同步)。 否則,它使用boost/smart_ptr/detail/atomic_count_pthreads.hppboost/smart_ptr/detail/atomic_count_win32.hpp或列出的其他文件中定義的實現。 這些是同步包裝類,確保所有操作都以原子方式完成。

volatile幾乎與線程無關。 看到這里

你誤讀了代碼。 如果代碼不使用多線程,則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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM