RAII线程安全吸气剂

第108节

大多数时候,我在代码中看到了线程安全的getter方法的这种实现的某些变体:

class A
{
public:

    inline Resource getResource() const
    {
        Lock lock(m_mutex);

        return m_resource;
    }

private:
    Resource m_resource;
    Mutex    m_mutex;
};

假设无法复制Resource,或者复制操作的计算成本过高,C ++中有没有办法避免返回的复制,但仍使用RAII样式锁定机制?

西蒙·克雷默

我还没有尝试过,但是类似的东西应该可以工作:

#include <iostream>
#include <mutex>
using namespace std;

typedef std::mutex Mutex;
typedef std::unique_lock<Mutex> Lock;

struct Resource {
    void doSomething() {printf("Resource::doSomething()\n"); }
};

template<typename MutexType, typename ResourceType>
class LockedResource
{
public:
    LockedResource(MutexType& mutex, ResourceType& resource) : m_mutexLocker(mutex), m_pResource(&resource) {}
    LockedResource(MutexType& mutex, ResourceType* resource) : m_mutexLocker(mutex), m_pResource(resource) {}
    LockedResource(LockedResource&&) = default;
    LockedResource(const LockedResource&) = delete;
    LockedResource& operator=(const LockedResource&) = delete;

    ResourceType* operator->()
    {
        return m_pResource;
    }

private:
    Lock m_mutexLocker;
    ResourceType* m_pResource;
};

class A
{
public:

    inline LockedResource<Mutex, Resource> getResource()
    {
        return LockedResource<Mutex, Resource>(m_mutex, &m_resource);
    }

private:
    Resource m_resource;
    Mutex    m_mutex;
};


int main()
{
    A a;
    { //Lock scope for multiple calls
        auto r = a.getResource();
        r->doSomething();
        r->doSomething();

        // The next line will block forever as the lock is still in use
        //auto dead = a.getResource();

    } // r will be destroyed here and unlock
    a.getResource()->doSomething();
    return 0;
}

但要小心,因为所访问资源的生存期取决于所有者(A的生存期


关于Godbolt的示例:链接

P1144很好地简化了生成的程序集,以便您可以看到锁的锁定和解锁位置。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章