abcdabcd987
abcdabcd987

Reputation: 2063

How do I atomically replace a vector?

I'm writing a multi-threaded program using C++11. I want to replace a vector atomically, while there may be some other worker threads iterating over the old vector. I don't care about if old workers' work is wasted, but I have to make sure that the replacement is atomic and new workers will get the new vector.

I think I probably need a std::atomic<std::shared_ptr<std::vector<T>>>>? However, since std::shared_ptr is not trivially copyable, it can't compile. The following code (seems?) works, but it leaks memory:

#include <atomic>
#include <memory>
#include <vector>
#include <thread>
#include <cstdio>

std::atomic<std::vector<int>*> v;

void read(const char* name) {
    long sum = 0;
    for (int x : *v) sum += x;
    printf("read(%s) sum = %ld\n", name, sum);
}

void replace() {
    v = new std::vector<int>(100, 2);
}

int main() {
    v = new std::vector<int>(10000000, 1);
    std::thread t1(read, "t1");
    std::thread t2(read, "t2");
    std::thread t3(replace);
    t3.join();
    std::thread t4(read, "t4");
    std::thread t5(read, "t5");
    t1.join();t2.join();t4.join();t5.join();
}

Upvotes: 2

Views: 748

Answers (1)

John Zwinck
John Zwinck

Reputation: 249582

shared_ptr is already thread safe, you don't (and can't) wrap it in atomic<>. Simply copy the shared_ptr in your reader, and in the writer you can swap it with a new one once you're done populating the new data.

Upvotes: 1

Related Questions