问题描述
我有一个C ++库,它应该做的事情上多线程一些计算。我做独立的线程code(即它们之间没有共享变量),除了一个阵列。问题是,我不知道如何使它线程安全的。
I have a C++ library, which supposed to do some computations on multiple threads. I made independent threads code (i.e. there are no shared variables between them), except for one array. The problem is, I don't know how to make it thread-safe.
我看着互斥锁定/解锁( QMutex
,因为我使用Qt),但它并不适合我的任务 - 当一个线程将锁定互斥,其他线程将等待!
I looked at mutex lock/unlock (QMutex
, as I'm using Qt), but it doesn't fit for my task - while one thread will lock the mutex, other threads will wait!
然后我读的std ::原子
,它看起来像正是我需要的。然而,我试图以下列方式使用:
Then I read about std::atomic
, which looked like exactly what I needed. Nevertheless, I tried to use it in the following way:
std::vector<std::atomic<uint64_t>> *myVector;
和它产生编译器错误(使用删除功能的std ::原子::原子(常量的std ::原子和放大器;)的的)。然后我发现 - 使用特殊包装的的std ::原子
。我想这样的:
And it produced compiler error (use of deleted function 'std::atomic::atomic(const std::atomic&)'). Then I found the solution - use special wrapper for std::atomic
. I tried this:
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;
这件事成功地编译,但是当我不能填满向量:
This thing compiles succesfully, but when I can't fill the vector:
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 );
}
我是什么做错了吗?我以为我什么都试过(也许不是,反正)并没有什么帮助。是否有任何其他方式为线程安全用C ++共享?
What am I doing wrong? I assume I tried everything (maybe not, anyway) and nothing helped. Are there any other ways for thread-safe array sharing in C++?
顺便说一句,我用MinGW的32位编译器4.7在Windows上。
By the way, I use MinGW 32bit 4.7 compiler on Windows.
推荐答案
下面是一个清理版本的 AtomicUInt64
键入
Here is a cleaned up version of your AtomicUInt64
type:
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;
和使用:
AtomicUInt64 value;
myVector->push_back ( value );
或
AtomicUInt64 value(x);
myVector->push_back ( value );
你的问题是你花了的std ::原子
按价值计算,这将导致一个副本,该副本将被阻止。哦,你无法从运算符=
返回。我也做了一些构造明确,可能是不必要的。并且我增加了常量
你的拷贝构造函数。
your problem was you took a std::atomic
by value, which causes a copy, which is blocked. Oh, and you failed to return from operator=
. I also made some constructors explicit, probably needlessly. And I added const
to your copy constructor.
我也被引诱加入商店
和负荷
方法 MobileAtomic
转发到 atomic.store
和 atomic.load
。
I would also be tempted to add store
and load
methods to MobileAtomic
that forwards to atomic.store
and atomic.load
.
这篇关于线程安全的无锁阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!