我一直在試圖編寫一個包裝類來包裝Win32內在函數,如InterlockedIncrement
,InterlockedExchange
。雖然我的問題可能與支持類似內部函數的其他平臺類似。如何編寫安全的原子對象包裝?
我有一個基本的模板類型:
template <typename T, size_t W = sizeof(T)>
class Interlocked {};
這部分是專門爲不同大小的數據類型。例如,這裏的32位之一:
//
// Partial specialization for 32 bit types
//
template<typename T>
class Interlocked <T, sizeof(__int32)>
{
public:
Interlocked<T, sizeof(__int32)>() {};
Interlocked<T, sizeof(__int32)>(T val) : m_val(val) {}
Interlocked<T, sizeof(__int32)>& Interlocked<T, sizeof(__int32)>::operator= (T val)
{
InterlockedExchange((LONG volatile *)&m_val, (LONG)val);
return *this;
}
Interlocked<T, sizeof(__int32)> Interlocked<T, sizeof(__int32)>::operator++()
{
return static_cast<T>(InterlockedIncrement((LONG volatile *)&m_val));
}
Interlocked<T, sizeof(__int32)> Interlocked<T, sizeof(__int32)>::operator--()
{
return static_cast<T>(InterlockedDecrement((LONG volatile *)&m_val));
}
Interlocked<T, sizeof(__int32)>& Interlocked<T, sizeof(__int32)>::operator+(T val)
{
InterlockedExchangeAdd((LONG volatile *)&m_val, (LONG) val);
return *this;
}
Interlocked<T, sizeof(__int32)>& Interlocked<T, sizeof(__int32)>::operator-(T val)
{
InterlockedExchangeSubtract((LONG volatile *)&m_val, (LONG) val);
return *this;
}
operator T()
{
return m_val;
}
private:
T m_val;
};
不過,我來,我不知道如何安全地寫出這樣的對象的結論。具體來說,我已經意識到,在執行互鎖操作後返回*this
允許另一個線程在返回之前更改該變量。這將使類型的點無效。可以寫這樣的東西嗎?大概的std ::原子解決了這個問題,但我沒有訪問,在我的編譯器...
謝謝我沒有意識到'boost :: atomic'。儘管我仍然想知道理論上如何做到這一點。 – Benj
@Benj:好的,我明白了。你可以看看它是如何在Boost中實現的 – nogard