La configuration de ma demande est un objet const partagé avec plusieurs threads. La configuration est stockée dans un emplacement centralisé et n'importe quel thread peut l'atteindre. J'ai essayé de construire une implémentation lockfree qui me permettrait de charger une nouvelle configuration tout en permettant aux autres threads de lire la dernière configuration connue.Lockfree Rechargement et partage des objets const
Mon implémentation actuelle a une course entre la mise à jour du shared_ptr
et sa lecture.
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;
};
Je peux ajouter un shared_mutex
pour l'accès en lecture/écriture problématique au shared_ptr
, mais je suis à la recherche d'une solution qui gardera la lockfree de mise en œuvre.
EDIT: Ma version de GCC ne prend pas en charge atomic_exchange
sur shared_ptr
EDIT2: Exigences Précision: je les lecteurs multiples et peut avoir plusieurs transbordeurs (bien que ce soit moins fréquent). Les lecteurs doivent contenir un objet de configuration et qu'il ne changera pas pendant qu'ils le lisent. Les anciens objets de configuration doivent être libérés lorsque le dernier lecteur est fini avec eux.
Pouvez-vous élaborer le cas d'utilisation? Si vous avez beaucoup de lecteurs, et qu'un thread décide de recharger, alors 1) Vous avez besoin d'un sémaphore, pas de mutex et 2) Quand les autres threads devraient-ils commencer à lire la nouvelle valeur? Ce n'est pas clairement défini jusqu'à quand ils devraient lire l'ancien. – kabanus
@kabanus Edité avec des clarifications. De plus, je voudrais éviter d'ajouter des mutex/sémaphores, si possible. – Shloim
Vous décrivez exactement un sémaphore en écriture. Les opérations de lecture sont libres, et l'écriture ne peut être faite que lorsque le sémaphore est clair. Tout ce que vous implémentez avec des compteurs serait juste cela. En supposant que l'assignation du pointeur n'est pas atomique, (cela pourrait être avec std :: atomic), vous devrez créer un sémaphore r/w. Je peux vous en montrer une, sinon je n'ai pas de solution. –
kabanus