4

我正在尝试实现一个简约的同步机制,其中一个对象包含一些 type 的值Foo,这Foo可能是一个重量级的类型,但很少改变它的值。该对象可以从多个线程访问,几乎 100% 读取。

我正在尝试一种方法来完成这项工作,而不需要对读者有任何锁定要求。我的第一次尝试是让我的类Foo通过类型的共享指针成员包含std::shared_ptr<Foo>。读取操作将简单地复制构造共享指针,取消引用它,然后使用该值的“版本”来做任何他们想做的事情。

写操作应该将它们的更改应用到 Foo 的新副本中,一旦完成,尝试Foo用新版本替换当前版本。

我意识到这是不可能的,shared_ptr<Foo>因为复制构造函数可能会进入读/写竞争,试图更新它,并读取损坏的值。我可以使用boost::intrusive_ptr<Foo>原子计数器解决这个问题并使用 CAS 操作进行版本更新,但仍然存在我无法摆脱的竞争条件:读者可以在调用intrusive_ptr_add_ref即将获取的实例之前暂停被另一个将计数降低到 0 的线程销毁。

这种方法似乎从根本上破坏了某些东西。

有什么方法可以不依赖临界区、读写器锁或成熟的 RCU(读取-复制-更新)来实现这一点?也许我错过了一些简单的东西。平台为 Win7+/x86/x64。

4

2 回答 2

4

解决方案是首先拥有一个std::shared_ptr<Foo>具有新的本地并通过原子分配方法Foo将其分配给全局。澄清:不要使用简单的分配。从链接中,您可以使用:std::shared_ptr

atomic_store( &global_ptr, std::make_shared<Foo>(...) );
于 2013-03-09T00:52:29.047 回答
0

这会工作..

Foo * globalFoo;
.
.

Foo* newFoo = new Foo();
Foo* temp;
do {
    temp = globalFoo;
} while(! std::atomic_compare_exchange_weak(temp, globalFoo, newFoo));
于 2013-03-09T01:12:27.687 回答