我知道,已經取得了一對夫婦面前的問題/答案很清楚,那volatile
是關係到C的可見狀態++內存模型,而不是多線程。可能揮發可以在用戶定義的類型,以幫助編寫線程安全的代碼
另一方面,Alexandrescu的article使用volatile
關鍵字不是作爲運行時功能,而是作爲編譯時檢查強制編譯器無法接受可能不是線程安全的代碼。在文章中,關鍵字的使用更像是required_thread_safety
標籤,而不是實際使用的volatile
。
這是(AB)利用volatile
合適?該方法可能隱藏了哪些可能的陷阱?
首先想到的是添加混淆:volatile
與線程安全無關,但由於缺乏更好的工具我可以接受它。
文章的基本簡化:
如果聲明一個變量volatile
,只有volatile
成員方法可以調用它,所以編譯器將阻止調用代碼的其他方法。聲明std::vector
實例爲volatile
將阻止該類的所有用途。添加一個形狀爲鎖定指針的包裝器,該指針執行const_cast
以釋放volatile
要求,任何通過鎖定指針的訪問都將被允許。
從文章偷竊:
template <typename T>
class LockingPtr {
public:
// Constructors/destructors
LockingPtr(volatile T& obj, Mutex& mtx)
: pObj_(const_cast<T*>(&obj)), pMtx_(&mtx)
{ mtx.Lock(); }
~LockingPtr() { pMtx_->Unlock(); }
// Pointer behavior
T& operator*() { return *pObj_; }
T* operator->() { return pObj_; }
private:
T* pObj_;
Mutex* pMtx_;
LockingPtr(const LockingPtr&);
LockingPtr& operator=(const LockingPtr&);
};
class SyncBuf {
public:
void Thread1() {
LockingPtr<BufT> lpBuf(buffer_, mtx_);
BufT::iterator i = lpBuf->begin();
for (; i != lpBuf->end(); ++i) {
// ... use *i ...
}
}
void Thread2();
private:
typedef vector<char> BufT;
volatile BufT buffer_;
Mutex mtx_; // controls access to buffer_
};
注意
後的第一對夫婦的答案的出現,我想我必須澄清,我可能還沒有使用最合適的詞。
使用的volatile
是因爲,因爲它意味着在編譯時它所提供的在運行但不是。也就是說,同樣的招數可以與const
關鍵字被拉如果它是在用戶定義類型,很少使用是volatile
是。也就是說,有一個關鍵字(它恰好被拼寫爲volatile)允許我阻止成員函數調用,Alexandrescu正在使用它來欺騙編譯器無法編譯線程不安全的代碼。
我認爲這是很多元編程技巧,在那裏,不是因爲他們在編譯的時候做了什麼,而是它所強制編譯器爲你做。
他們正在討論目前在comp.lang.C++。moderated中的代碼。 – 2010-03-22 20:12:49
@Johannes:這是他們每十年必須進行兩次的討論嗎?我記得Andrei發表這篇文章時激烈的討論。就像這裏一樣,大部分的熱量是由於人們只是在同一篇文章中閱讀「易失性」和「線索」而引起的,並且甚至沒有試圖理解這個想法是什麼。 – sbi 2011-04-05 07:29:36