Я нашел shared_ptr и weak_ptr, длинный со списком, выполнил работу, в которой я нуждался.Моя проблема заключалась в том, что у меня было несколько клиентов, желающих взаимодействовать с внутренними данными хоста.Обычно хост обновляет данные самостоятельно, однако, если клиент запрашивает его, хост должен прекратить обновление, пока клиенты не получат доступ к данным хоста.В то же время клиент может запросить монопольный доступ, чтобы ни другие клиенты, ни хост не могли изменить данные этого хоста.
Как я это сделал, я создал структуру:
struct UpdateLock
{
typedef std::shared_ptr< UpdateLock > ptr;
};
У каждого клиента будет такой член:
UpdateLock::ptr m_myLock;
Тогда у хоста будет элемент слабой_птр для исключительности и список слабых_птр для неисключительных блокировок:
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 ()).
Очередь может быть добавлена для смягчения между исключительными и неисключительными блокировками,однако до сих пор у меня не было коллизий, поэтому я собираюсь подождать, пока это произойдет, чтобы добавить решение (в основном, так что у меня есть условия тестирования в реальном мире).
Пока это хорошо работает для моих нужд;Я могу себе представить необходимость его расширения и некоторые проблемы, которые могут возникнуть из-за расширенного использования, однако, это было быстро реализовано и требовало очень мало пользовательского кода.