C ++,x86-64中的读写线程安全智能指针 [英] Read-write thread-safe smart pointer in C++, x86-64
问题描述
我开发一些无锁的数据结构,并出现以下问题。
I develop some lock free data structure and following problem arises.
我有写线程在堆上创建对象,并将它们包含在智能指针与引用计数器。我也有很多读者线程,那些工作与这些对象。代码如下所示:
I have writer thread that creates objects on heap and wraps them in smart pointer with reference counter. I also have a lot of reader threads, that work with these objects. Code can look like this:
SmartPtr ptr;
class Reader : public Thread {
virtual void Run {
for (;;) {
SmartPtr local(ptr);
// do smth
}
}
};
class Writer : public Thread {
virtual void Run {
for (;;) {
SmartPtr newPtr(new Object);
ptr = newPtr;
}
}
};
int main() {
Pool* pool = SystemThreadPool();
pool->Run(new Reader());
pool->Run(new Writer());
for (;;) // wait for crash :(
}
当我创建 ptr
的线程本地副本时,意味着至少
When I create thread-local copy of ptr
it means at least
- 地址。
- 增加引用计数器。
因此有时我的读者使用已删除的对象。
I can't do these two operations atomically and thus sometimes my readers work with deleted object.
问题是 - 我应该使用什么样的智能指针来从多个线程读取访问, ?解决方案应该存在,因为Java程序员甚至不关心这样的问题,只是依赖于所有对象都是引用,只有当没有人使用它们时才删除。
The question is - what kind of smart pointer should I use to make read-write access from several threads with correct memory management possible? Solution should exist, since Java programmers don't even care about such a problem, simply relying on that all objects are references and are deleted only when nobody uses them.
对于PowerPC,我发现 http://drdobbs.com/184401888 ,看起来不错,但使用Load-Linked和Store-Conditional指令,我们没有在x86。
For PowerPC I found http://drdobbs.com/184401888, looks nice, but uses Load-Linked and Store-Conditional instructions, that we don't have in x86.
据我所知,boost指针提供这样的功能只使用锁。我需要无锁解决方案。
As far I as I understand, boost pointers provide such functionality only using locks. I need lock free solution.
推荐答案
boost :: shared_ptr有atomic_store,它使用一个无锁的自旋锁,足够用于99%的可能情况。
boost::shared_ptr have atomic_store which uses a "lock-free" spinlock which should be fast enough for 99% of possible cases.
boost::shared_ptr<Object> ptr;
class Reader : public Thread {
virtual void Run {
for (;;) {
boost::shared_ptr<Object> local(boost::atomic_load(&ptr));
// do smth
}
}
};
class Writer : public Thread {
virtual void Run {
for (;;) {
boost::shared_ptr<Object> newPtr(new Object);
boost::atomic_store(&ptr, newPtr);
}
}
};
int main() {
Pool* pool = SystemThreadPool();
pool->Run(new Reader());
pool->Run(new Writer());
for (;;)
}
编辑:
响应下面的注释,实现在boost / shared_ptr.hpp...
In response to comment below, the implementation is in "boost/shared_ptr.hpp"...
template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
{
boost::detail::spinlock_pool<2>::scoped_lock lock( p );
p->swap( r );
}
template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r )
{
boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
sp.lock();
p->swap( r );
sp.unlock();
return r; // return std::move( r )
}
这篇关于C ++,x86-64中的读写线程安全智能指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!