假设我们在C++11程序中使用标准的消费者/生产者模式:(来自:
http://en.cppreference.com/w/cpp/atomic/memory_order
)
#include <thread>
#include <atomic>
#include <cassert>
#include <string>
std::atomic<std::string*> ptr;
int data;
void producer()
{
std::string* p = new std::string("Hello");
ptr.store(p, std::memory_order_release);
}
void consumer()
{
std::string* p2;
while (!(p2 = ptr.load(std::memory_order_consume)))
;
assert(*p2 == "Hello"); // never fires: *p2 carries dependency from ptr
// yea well, it actually uses p2 for quite a while probably....
}
int main()
{
std::thread t1(producer);
std::thread t2(consumer);
t1.join(); t2.join();
}
现在,我想稍微改变一下生产者代码的行为。我不想简单地设置字符串,而是希望它
覆盖
字符串。例如。:
void producer()
{
std::string* p = new std::string("Hello");
ptr.store(p, std::memory_order_release);
// do some stuff
std::string* p2 = new std::string("Sorry, should have been Hello World");
ptr.store(p2, std::memory_order_release);
// **
}
这里的制作人负责弦的生成,这意味着在我的简单世界中,它也应该对这些弦的破坏负责。
因此,在标有“**”的行中,我们应该销毁字符串“p”,这就是这个问题的意义所在。
您可能会考虑的解决方案是添加(在标记行处):
delete p;
然而,这会破坏程序,因为在我们删除字符串之后,使用者可能会使用字符串——毕竟,使用者使用的是指针。此外,这意味着生产者等待消费者,这是不必要的——我们只是想清理我们的旧记忆。使用引用计数智能指针似乎是不可能的,因为原子只支持这么多类型。
解决此问题的最佳(最有效)方法是什么?