【发布时间】:2013-05-30 23:14:44
【问题描述】:
我有一个 C++ 库,它应该在多个线程上进行一些计算。我制作了独立的线程代码(即它们之间没有共享变量),除了一个数组。问题是,我不知道如何使它成为线程安全的。
我查看了互斥锁/解锁(QMutex,因为我正在使用 Qt),但它不适合我的任务 - 虽然一个线程会锁定互斥锁,但其他线程会等待!
然后我读到了std::atomic,它看起来正是我所需要的。尽管如此,我还是尝试通过以下方式使用它:
std::vector<std::atomic<uint64_t>> *myVector;
并且它产生了编译器错误(使用已删除的函数'std::atomic::atomic(const std::atomic&)')。然后我找到了the solution - 为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;
这个东西编译成功了,但是当我无法填充向量时:
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++ 中还有其他方法可以实现线程安全的数组共享吗?
顺便说一句,我在 Windows 上使用 MinGW 32bit 4.7 编译器。
【问题讨论】:
-
您想要一个固定大小(在多线程部分)的共享元素数组还是共享元素数组。我的意思是,数组中的插入和删除是否存在于代码的多线程部分中?
-
数组的大小是固定的——我没有在线程中插入或删除。
-
@ahawkthomas:你 push_back,这通常会改变大小......
-
那么,如何在不使用
push_back的情况下初始化std::vector?对于这些愚蠢的问题,我很抱歉,但除了std::vector t = { 0, 0, 0 },我什么都不知道——而且这种方法显然对大量项目没有用处。 -
另外,你明白吗,你的包装操作不是原子操作。
标签: c++ arrays thread-safety