线程安全的无锁阵列

aha*_*mas 8 c++ arrays thread-safety

我有一个C++库,它应该在多个线程上进行一些计算.我创建了独立的线程代码(即它们之间没有共享变量),除了一个数组.问题是,我不知道如何使其成为线程安全的.

我看了互斥锁/解锁(QMutex因为我正在使用Qt),但它不适合我的任务 - 而一个线程将锁定互斥锁,其他线程将等待!

然后我读到了std::atomic,看起来就像我需要的那样.不过,我尝试以下列方式使用它:

std::vector<std::atomic<uint64_t>> *myVector;
Run Code Online (Sandbox Code Playgroud)

并且它产生了编译器错误(使用已删除的函数'std :: atomic :: atomic(const std :: atomic&)').然后我找到了解决方案 - 使用特殊的包装器std::atomic.我试过这个:

struct AtomicUInt64
{
    std::atomic<uint64_t> atomic;

    AtomicUInt64() : atomic() {}

    AtomicUInt64 ( std::atomic<uint64_t> a ) : atomic ( atomic.load() ) {}

    AtomicUInt64 ( AtomicUInt64 &auint64 ) : atomic ( auint64.atomic.load() ) {}

    AtomicUInt64 &operator= ( AtomicUInt64 &auint64 )
    {
                atomic.store ( auint64.atomic.load() );
    }
};

std::vector<AtomicUInt64> *myVector;
Run Code Online (Sandbox Code Playgroud)

这个东西成功编译,但是当我无法填充向量时:

myVector = new std::vector<AtomicUInt64>();

for ( int x = 0; x < 100; ++x )
{
    /* This approach produces compiler error:
     * use of deleted function 'std::atomic<long long unsigned int>::atomic(const std::atomic<long long unsigned int>&)'
     */
    AtomicUInt64 value( std::atomic<uint64_t>( 0 ) ) ;
    myVector->push_back ( value );

    /* And this one produces the same error: */
    std::atomic<uint64_t> value1 ( 0 );
    myVector->push_back ( value1 );
}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我假设我尝试了一切(也许不是,但无论如何)并没有任何帮助.在C++中有没有其他方法可以进行线程安全的数组共享?

顺便说一下,我在Windows上使用MinGW 32bit 4.7编译器.

Yak*_*ont 6

这是您的AtomicUInt64类型的清理版本:

template<typename T>
struct MobileAtomic
{
  std::atomic<T> atomic;

  MobileAtomic() : atomic(T()) {}

  explicit MobileAtomic ( T const& v ) : atomic ( v ) {}
  explicit MobileAtomic ( std::atomic<T> const& a ) : atomic ( a.load() ) {}

  MobileAtomic ( MobileAtomic const&other ) : atomic( other.atomic.load() ) {}

  MobileAtomic& operator=( MobileAtomic const &other )
  {
    atomic.store( other.atomic.load() );
    return *this;
  }
};

typedef MobileAtomic<uint64_t> AtomicUInt64;
Run Code Online (Sandbox Code Playgroud)

并使用:

AtomicUInt64 value;
myVector->push_back ( value );
Run Code Online (Sandbox Code Playgroud)

要么:

AtomicUInt64 value(x);
myVector->push_back ( value );
Run Code Online (Sandbox Code Playgroud)

你的问题是你拿了一个std::atomic值,这会导致一个被阻止的副本.哦,你没有回来operator=.我也做了一些明确的构造函数,可能是不必要的.我添加const到你的拷贝构造函数中.

我也很想添加storeload方法MobileAtomic转发到atomic.storeatomic.load.