dimanche 4 janvier 2015

C++11 Thread Safety of Atomic Containers

I am trying to implement a thread safe STL vector without mutexes. So I followed through this post and implemented a wrapper for the atomic primitives.


However when I ran the code below, it displayed out Failed!twice from the below code (only two instances of race conditions) so it doesn't seem to be thread safe. I'm wondering how can I fix that?


Wrapper Class



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

AtomicVariable() : atomic(T()) {}

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

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

inline AtomicVariable& operator=(AtomicVariable const &rhs) {
atomic.store(rhs.atomic.load());
return *this;
}

inline AtomicVariable& operator+=(AtomicVariable const &rhs) {
atomic.store(rhs.atomic.load() + atomic.load());
return *this;
}

inline bool operator!=(AtomicVariable const &rhs) {
return !(atomic.load() == rhs.atomic.load());
}
};

typedef AtomicVariable<int> AtomicInt;


Functions and Testing



// Vector of 100 elements.
vector<AtomicInt> common(100, AtomicInt(0));

void add10(vector<AtomicInt> &param){
for (vector<AtomicInt>::iterator it = param.begin();
it != param.end(); ++it){
*it += AtomicInt(10);
}
}

void add100(vector<AtomicInt> &param){
for (vector<AtomicInt>::iterator it = param.begin();
it != param.end(); ++it){
*it += AtomicInt(100);
}
}

void doParallelProcessing(){

// Create threads
std::thread t1(add10, std::ref(common));
std::thread t2(add100, std::ref(common));

// Join 'em
t1.join();
t2.join();

// Print vector again
for (vector<AtomicInt>::iterator it = common.begin();
it != common.end(); ++it){
if (*it != AtomicInt(110)){
cout << "Failed!" << endl;
}
}
}


int main(int argc, char *argv[]) {

// Just for testing purposes
for (int i = 0; i < 100000; i++){
// Reset vector
common.clear();
common.resize(100, AtomicInt(0));
doParallelProcessing();
}
}


Is there such a thing as an atomic container? I've also tested this with a regular vector<int> it didn't have any Failed output but that might just be a coincidence.


Aucun commentaire:

Enregistrer un commentaire