我在写一个使用C++ 11的多线程程序。我想以原子方式替换一个矢量,而可能有一些其他工作线程遍历旧矢量。我不在乎老员工的工作是否浪费,但我必须确保替代品是原子的,新员工将获得新的工作。我想我可能需要std::atomic<std::shared_ptr<std::vector<T>>>>
?但是,由于std::shared_ptr
不是可以复制的,所以不能编译。下面的代码(?似乎)的作品,但它泄漏内存:如何以原子方式替换矢量?
#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();
}
您可能想要看看[RCU](https://lwn.net/Articles/262464/)这样的方法,其中编写者可以通过'memory_order_release'自动切换指向结构的指针,而读取器通过'memory_order_consume'安全地读取,并且只有一次认为没有新的读者可以观察旧的指针,作者才能够回收内存。当然,其他记忆回收策略也会起作用,包括危险指针和参考计数。 – Alejandro
t3在t2进入read()函数体之前,这里可以替换向量。 –