大多数时候,我在代码中看到了线程安全的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] 删除。
我来说两句