Конфигурация моего приложения представляет собой объект const, который совместно используется несколькими потоками. Конфигурация хранится в централизованном месте, и любой поток может достичь этого. Я попытался создать реализацию lockfree, которая позволила бы мне загружать новую конфигурацию, позволяя другим потокам читать последнюю известную конфигурацию.Lockfree Перезагрузка и совместное использование объектов const
В моей текущей реализации есть гонка между обновлением shared_ptr
и чтением с нее.
template<typename T>
class ConfigurationHolder
{
public:
typedef std::shared_ptr<T> SPtr;
typedef std::shared_ptr<const T> CSPtr;
ConfigurationHolder() : m_active(new T()) {}
CSPtr get() const { return m_active; } // RACE - read
template<typename Reloader>
bool reload(Reloader reloader)
{
SPtr tmp(new T());
if (!tmp)
return false;
if (!reloader(tmp))
return false;
m_active=tmp; // RACE - write
return true;
}
private:
CSPtr m_active;
};
Я могу добавить shared_mutex
для проблемного доступа на чтение/запись к shared_ptr
, но я ищу решение, которое будет держать lockfree реализации.
EDIT: Моя версия GCC не поддерживает atomic_exchange
на shared_ptr
edit2: Требования Разъяснения: У меня есть несколько читателей, и может иметь несколько перегружателей (хотя это менее распространено). Читателям необходимо удержать объект конфигурации и что он не изменится во время чтения. Старые объекты конфигурации должны быть освобождены, когда последний читатель будет с ними выполнен.
Можете ли вы разработать прецедент? Если у вас много читателей, и один поток решает перезагрузить, то 1) вам нужен семафор, а не мьютекс, и 2) Когда другие потоки начнут читать новое значение? Это четко не определено до тех пор, пока они не прочитают старый. – kabanus
@kabanus Отредактировано с пояснениями. Кроме того, я хотел бы избежать добавления мьютексов/семафоров, если это возможно. – Shloim
Вы точно описываете семафор чтения. Операции чтения бесплатны, и запись может быть выполнена только тогда, когда семафор ясен. Все, что вы реализуете с помощью счетчиков, будет именно этим. Предполагая, что назначение указателя не является атомарным (оно может быть с std :: atomic), вам нужно сделать r/w семафор. Я могу показать вам одну из них, иначе у меня нет решения. –
kabanus