C ++,x86-64中的读写线程安全智能指针 [英] Read-write thread-safe smart pointer in C++, x86-64

查看:289
本文介绍了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


  1. 地址。

  2. 增加引用计数器。

因此有时我的读者使用已删除的对象。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆