我一直在尝试编写一个包装类来包装 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::atomic 解决了这个问题,但我无法在我的编译器中访问它......