在VC ++中的1个原子操作中,将值设置为POD(不具有构造函数/结构体) [英] Set a value to POD (that doesn't have constructor/desctructor) within 1 atomic operation in VC++

查看:301
本文介绍了在VC ++中的1个原子操作中,将值设置为POD(不具有构造函数/结构体)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一种方法来设置没有构造函数/析构函数(int,byte,long等)作为原子操作的POD。



我需要的原因是因为我想使用__declspec(线程)为了有一个TLSint作为线程本地存储。事情是,目前的VC ++编译器不支持具有构造函数/析构函数的对象,所以我声明:

  static __declspec )int _thread_val; 

接下来,我要设置 _thread_val



使用std :: atomic不工作,因为它有构造函数/析构函数,因此不支持:

  static __declspec(thread)std :: atomic< int> _thread_val; //不在VC ++中编译



我也在VC内部函数中查找,



有没有人知道如何做?

解决方案

不幸的是,Microsoft的实现 std :: atomic< T> 是不符合通过没有一个琐碎的默认构造函数。你可以通过使用包装类来解决这个问题。因为你知道 std :: atomic< T> 在没有被构造时应该是可用的(因为你知道它应该是一个POD类型) ,也不需要破坏,你可以使用 std :: aligned_storage 来保存对象。这是一个起点,它可能需要轻微调整取决于你会遇到的编译器特定的怪癖。

  template< typename T> 
class atomic_wrapper
{
std :: aligned_storage< sizeof(std :: atomic< T>),alignof(std :: atomic&数据;
public:
atomic_wrapper()= default;
atomic_wrapper(const atomic_wrapper< T>&)= delete;
std :: atomic< T> & operator *(){return reinterpret_cast< std :: atomic< T> &>(data); }
std :: atomic< T> * operator - >(){return& ** this; }
};

现在,不是将变量声明为 std :: atomic< int> a; ,声明为 atomic_wrapper< int> a; ,并更新您的访问以使用 * a 而不是 a p>

I am trying to find a way to set a POD that doesn't have constructor/destructor (int, byte, long etc.) as atomic operation.

The reason I need that is because I want to use __declspec(thread) in order to have a TLS "int" as a thread local storage. The thing is that current VC++ compiler doesn't support objects that have constructor/destructor, so I declared:

static __declspec(thread) int _thread_val;

Next, I want to set that _thread_val atomically.

Using std::atomic doesn't work because it has constructor/destructor, therefore it is not supported:

static __declspec(thread) std::atomic<int> _thread_val; //doesn't compile in VC++

I also looked in VC intrinsic functions, but didn't find exactly what I wanted (guess due to lack of documentation).

Does anyone know how to do it?

解决方案

It is unfortunate that Microsoft's implementation of std::atomic<T> is non-conforming by not having a trivial default constructor. You may be able to work around that by using a wrapper class. Since you know that std::atomic<T> is supposed to be usable when it hasn't been constructed (since you know that it is supposed to be a POD type), and doesn't require destruction either, you can use std::aligned_storage to hold the object. Here's a starting point, it may need slight tweaking depending on the compiler-specific quirks you'll encounter.

template <typename T>
class atomic_wrapper
{
    std::aligned_storage<sizeof(std::atomic<T>), alignof(std::atomic<T>)> data;
public:
    atomic_wrapper() = default;
    atomic_wrapper(const atomic_wrapper<T> &) = delete;
    std::atomic<T> &operator *() { return reinterpret_cast<std::atomic<T> &>(data); }
    std::atomic<T> *operator ->() { return &**this; }
};

Now, instead of declaring a variable as std::atomic<int> a;, declare it as atomic_wrapper<int> a;, and update your accesses to use *a instead of a.

这篇关于在VC ++中的1个原子操作中,将值设置为POD(不具有构造函数/结构体)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆