목록이 긴 shared_ptr과 weak_ptr이 필요한 작업을 수행했습니다. 내 문제는 호스트의 내부 데이터와 상호 작용하려는 여러 클라이언트가 있다는 것입니다. 일반적으로 호스트는 자체적으로 데이터를 업데이트하지만 클라이언트가 요청하면 클라이언트가 호스트 데이터에 액세스하지 않을 때까지 호스트 업데이트를 중지해야합니다. 동시에 클라이언트는 단독 액세스를 요청할 수 있으므로 다른 클라이언트 나 호스트가 해당 호스트 데이터를 수정할 수 없습니다.
내가 이것을 한 방법은 구조체를 만들었습니다.
struct UpdateLock
{
typedef std::shared_ptr< UpdateLock > ptr;
};
각 고객에게는 다음과 같은 구성원이 있습니다.
UpdateLock::ptr m_myLock;
그러면 호스트는 독점 성을위한 weak_ptr 멤버와 비 배타적 잠금을위한 weak_ptr 목록을 갖게됩니다.
std::weak_ptr< UpdateLock > m_exclusiveLock;
std::list< std::weak_ptr< UpdateLock > > m_locks;
잠금을 활성화하는 기능과 호스트가 잠겨 있는지 확인하는 다른 기능이 있습니다.
UpdateLock::ptr LockUpdate( bool exclusive );
bool IsUpdateLocked( bool exclusive ) const;
LockUpdate, IsUpdateLocked 및 주기적으로 호스트의 업데이트 루틴에서 잠금을 테스트합니다. 잠금 테스트는 weak_ptr이 만료되었는지 확인하고 m_locks 목록에서 만료 된 항목을 제거하는 것 (호스트 업데이트 중에 만 수행)만큼 간단합니다. 목록이 비어 있는지 확인할 수 있습니다. 동시에 클라이언트가 걸려있는 shared_ptr을 재설정하면 자동 잠금 해제가 발생하며 클라이언트가 자동으로 파괴 될 때도 발생합니다.
모든 효과는 클라이언트가 독점 성을 거의 필요로하지 않기 때문에 (일반적으로 추가 및 삭제 전용으로 예약 됨) 대부분의 경우 LockUpdate (false)에 대한 요청, 즉 비 독점은 (! m_exclusiveLock)만큼 성공합니다. 독점 성 요청 인 LockUpdate (true)는 (! m_exclusiveLock) 및 (m_locks.empty ()) 모두에 대해서만 성공합니다.
배타적 잠금과 배타적 잠금을 완화하기 위해 대기열을 추가 할 수는 있지만 지금까지 충돌은 없었으므로 솔루션을 추가 할 때까지 기다릴 것입니다 (대부분 실제 테스트 조건이 있습니다).
지금까지 이것은 내 요구에 잘 작동합니다. 나는 이것을 확장해야 할 필요성과 확장 된 사용으로 인해 발생할 수있는 몇 가지 문제를 상상할 수 있지만, 구현이 빠르고 사용자 정의 코드가 거의 필요하지 않았습니다.